package controllers;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;


import models.*;

import org.apache.commons.mail.DefaultAuthenticator;
import org.apache.commons.mail.EmailException;
import org.apache.commons.mail.SimpleEmail;

import play.data.validation.Email;
import play.data.validation.Required;
import play.db.jpa.Blob;
import play.libs.Codec;
import play.mvc.Controller;

public class Application extends Controller {
	/**
	 * It renders the index.html if the userId does not exist in the session
	 * which means the user is not loged in, if the userId exists it calls
	 * Home().
	 * 
	 * @author Shady
	 * 
	 */
	public static void index() {
		if (session.get("userId") != null) {
			Home();
		} else {
			render();
		}
	}

	/**
	 * It renders Home.html
	 * 
	 * @author Shady
	 * @author Nada Mohamed it renders the users highest contributions
	 */

	public static void Home() {
		List<User> highContributed = communityContributionsList();
		render(highContributed);
	}

	/**
	 * It renders getPassword.html from which the User can send request to get
	 * his/her password.
	 * 
	 * @author Shady
	 */
	public static void getPassword() {
		render();
	}

	/**
	 * It renders the signUp form from signUp.html
	 * 
	 * @author Shady
	 */
	public static void signUp() {
		render();
	}

	/**
	 * It renders adminLogin.html from where the administrator logs in to the
	 * administration system.
	 * 
	 * @author Shady
	 */
	public static void adminLogin() {
		render();
	}

	/**
	 * 
	 * @author emam
	 */
	/*
	 * the method task is to call the topic html file
	 */
	public static void Topic(long depId) {
		long id = Long.parseLong(session.get("orgId"));
		Organization org = Organization.findById(id);
		Department dep = Department.findById(depId);
		render(dep, org);
	}

	/**
	 * 
	 * Renders the list of all organizations if and only if the user is logged
	 * in as it seeks the userId in the session.
	 * 
	 * @author Heba
	 */

	public static void orgList() {
		if (session.get("userId") != null) {
			long id = Long.parseLong(session.get("userId"));
			User user = User.findById(id);
			List<Organization> lst = Organization.findAll();
			render(lst, user);
		} else {
			validation.addError("email", "Please Login First");
			validation.keep(); // for nxt request
			index();
		}
	}

	/**
	 * 
	 * Retrieves its view with list of all users that are not organization leads
	 * in this organization and all departments in this organization.
	 * 
	 * @author heba
	 */
	public static void assignRole() {

		long organizationId = Long.parseLong(session.get("orgId"));
		Organization org = Organization.findById(organizationId);
		List<Department> dList = org.department;
		List<HasRoleInOrganization> allNotOrgLeads = HasRoleInOrganization
				.find("Organization_id = ? AND Role_Id != ?", organizationId,
						(long) 1).fetch();
		List<User> uList = new ArrayList<User>();
		boolean userAdded = false;
		for (int i = 0; i < allNotOrgLeads.size(); i++) {
			for (int j = 0; j < uList.size(); j++) {
				if (allNotOrgLeads.get(i).user.id == uList.get(j).id) {
					userAdded = true;
				}
			}
			if (!userAdded) {
				uList.add(allNotOrgLeads.get(i).user);
			}
		}
		boolean isOrgLead = roleIsOrgLead();
		render(org, uList, dList, isOrgLead);
	}

	/**
	 * 
	 * Takes the userId from the view and retrieve the current viewing
	 * organization id from the session. Then sends the user Id and ,
	 * organization Id and role Id = 1 (Organization Lead) to addRole(userId,
	 * organizationId, roleId) to add the HasRoleInOrganization in the model if
	 * addRole method returned true which means the role added successfully the
	 * method sends validation message as an error to the view confirming the
	 * role addition. Else if returned false which means the role is not added
	 * the method sends a validation message as error informing that the
	 * addition process failed.
	 * 
	 * @author heba
	 * @param uList
	 *            the user ID that is sent from assignRole.html.
	 */

	public static void setOrgLead(long uList) {
		long id = Long.parseLong(session.get("orgId"));
		long roleId = 1;
		if (addRole(uList, roleId, id)) {
			long userId = Long.parseLong(session.get("userId"));
			Organization organization = Organization.findById(id);
			List<User> toNotifyUsers = organization.toBeNotified;
			User user = User.findById(uList);
			User orgLead = User.findById(userId);
			for (int i = 0; i < toNotifyUsers.size(); i++) {
				User toNotify = toNotifyUsers.get(i);
				if (toNotify.notifyOnOrganization) {
					String action = "User " + user.nickName
							+ " has been assigned as "
							+ "organization lead in organization "
							+ organization.name + "by the organization lead "
							+ orgLead.nickName;

					Notification notif = new Notification(action, "System",
							toNotify, new Date());
					notif.save();
				}
			}
			validation.addError("assigned", "The User Assigned");
			validation.keep();
			assignRole();
		} else {
			validation.addError("assigned",
					"The User is already assigned to this role before");
			validation.keep();
			assignRole();
		}

	}

	/**
	 * 
	 * 
	 * Takes the user Id and the department Id, retrieves the current
	 * organization Id from the session and set the role Id = 2 (Organizer),
	 * retrieves the User, Organization, and Department from the database by ID
	 * then if the user and department and role is not exist in
	 * OrganizerInOrganization it create new OrganizerInOrganization object,
	 * sends the user Id, organization Id , role Id to addRole(userId,
	 * organizationId, roleId) to add the HasRoleInOrganization object if not
	 * exist then if the objects are added successfully to the Models a message
	 * as a validation error sent to assignRole view confirming the assigning
	 * process else a failure message is sent.
	 * 
	 * @author Heba
	 * @param uList
	 *            the user Id that is sent from assignRole.html
	 * @param dList
	 *            the department Id that is sent from assignRole.html
	 */

	public static void setOrganizer(long uList, long dList) {

		long roleId = 2;
		Role role = Role.findById(roleId);
		User user = User.findById(uList);
		Department dep = Department.findById(dList);
		long id = Long.parseLong(session.get("orgId"));
		if ((OrganizerInOrganization.count("Department_id = ? AND User_id = ?",
				dList, uList) == 0) && addRole(uList, roleId, id)) {
			OrganizerInOrganization orgnizer = new OrganizerInOrganization(
					user, role, dep);
			orgnizer.save();
			dep.toBeNotified.add(user);
			Organization organization = Organization.findById(id);
			List<User> toNotifyUsers = organization.toBeNotified;
			long userId = Long.parseLong(session.get("userId"));
			User orgLead = User.findById(userId);
			for (int i = 0; i < toNotifyUsers.size(); i++) {
				User toNotify = toNotifyUsers.get(i);
				if (toNotify.notifyOnOrganization) {
					String action = "User " + user.nickName
							+ " has been assigned as "
							+ "organizer in department " + dep.name
							+ " in organization " + organization.name
							+ "by the organization lead " + orgLead.nickName;

					Notification notif = new Notification(action, "System",
							toNotify, new Date());
					notif.save();
				}
			}
			validation.addError("assigned", "The User Assigned");
			validation.keep();
			assignRole();
		} else {
			validation.addError("assigned",
					"The User is already assigned to this department before");
			validation.keep();
			assignRole();
		}
	}

	/**
	 * Takes the department Id and retrieve its view with the organization in
	 * use, list of all idea developers in this organization, and the department
	 * in use. It also retrieve the list of all blocks in this department.
	 * 
	 * @author Heba
	 * 
	 * @param depId
	 *            Department Id
	 */

	public static void blockUserFromDepartment(long depId) {
		long organizationId = Long.parseLong(session.get("orgId"));
		Organization org = Organization.findById(organizationId);
		Department department = Department.findById(depId);
		List<HasRoleInOrganization> allIdeaDevelopers = HasRoleInOrganization
				.find("Organization_id = ? AND Role_Id = ?", organizationId,
						(long) 3).fetch();
		List<IdeaDeveloperBlockedFromDepartment> allBlocked = IdeaDeveloperBlockedFromDepartment
				.find("Department_id = ? ", depId).fetch();
		render(org, department, allIdeaDevelopers, allBlocked);
	}

	/**
	 * Get valid department Id, user Id and String reason. if the block does not
	 * exist it retrieves User and Department by ID from the database and
	 * creates new instance of IdeaDeveloperBlockedFromDepartment with User,
	 * Department, reason, and current date. Retrieve the user Id and
	 * organization Id from the session and get the current User (Organization
	 * Lead that set the block) and Organization from the database to set the
	 * action that will be sent as a notification to the blocked user. Creates
	 * new instance of Notification with the name of the organization lead and
	 * the reason of the block. And send notification to all organizers in this
	 * organization. Finally it calls IdeaDeveloperBlockedFromDepartment() with
	 * message sent as validation error confirming the block. If the block
	 * exists it calls IdeaDeveloperBlockedFromDepartment() with message sent as
	 * validation error informing the existence of the block before.
	 * 
	 * @param departmentId
	 *            Department ID
	 * @param userId
	 *            User ID
	 * @param reason
	 *            The Reason of the block
	 */

	public static void doBlockUserFromDepartment(
			long departmentId,
			long userId,
			@Required(message = "Please Spicify the reason of Block") String reason) {
		if (userId < 1) {
			validation.addError("reason", "Please Select the user");
			validation.keep();
			blockUserFromDepartment(departmentId);
		} else {
			User user = User.findById(userId);
			Department department = Department.findById(departmentId);
			if (IdeaDeveloperBlockedFromDepartment.count(
					"Department_id = ? AND User_id = ?", departmentId, userId) == 0) {
				Date inDate = new Date();
				IdeaDeveloperBlockedFromDepartment newBlock = new IdeaDeveloperBlockedFromDepartment(
						user, department, reason, inDate);
				long organizationId = Long.parseLong(session.get("orgId"));
				Organization org = Organization.findById(organizationId);
				long orgLeadId = Long.parseLong(session.get("userId"));
				User orgLead = User.findById(orgLeadId);
				String action = "You have been blocked by the Organization Lead "
						+ orgLead.nickName
						+ " of Organization "
						+ org.name
						+ " because: " + reason;
				Notification notif = new Notification(action, orgLead.nickName,
						user, inDate);
				newBlock.save();
				notif.save();
				List<HasRoleInOrganization> allOrganizers = HasRoleInOrganization
						.find("Organization_id = ? AND Role_id = ?", org.id,
								(long) 2).fetch();
				for (int i = 0; i < allOrganizers.size(); i++) {
					HasRoleInOrganization organizerRole = allOrganizers.get(i);
					User organizer = organizerRole.user;
					if (organizer.notifyOnDepartment
							&& organizer.notifyOnOrganization) {
						action = "User "
								+ user.nickName
								+ " have been blocked by the Organization Lead "
								+ orgLead.nickName + " because: " + reason;
						Notification notifForOrganizer = new Notification(
								action, "System", organizer, inDate);
						notifForOrganizer.save();
					}

				}
				validation.addError("reason", "User Has Been Blocked");
				validation.keep();
				blockUserFromDepartment(departmentId);
			} else {
				validation.addError("reason",
						"User Has Been already Blocked before");
				validation.keep();
				blockUserFromDepartment(departmentId);
			}
		}
	}

	/**
	 * It takes the department Id, user Id, and the reason of the Unblock, then
	 * it retrieves the IdeaDeveloperBlockedFromDepartment entry that represent
	 * the block of the user in this department from the database by the Id of
	 * the department and the user. It deletes the block and send a validation
	 * message confirming the unBlock.
	 * 
	 * @author Heba
	 * @param departmentId
	 *            Department Id
	 * @param userId
	 *            User Id
	 * @param reason
	 *            String
	 */
	public static void doUnblockUserFromDepartment(
			long departmentId,
			long userId,
			@Required(message = "Please Spicify the reason of Block") String reason) {
		if (userId < 1) {
			validation.addError("reason", "Please Select the user");
			validation.keep();
			blockUserFromDepartment(departmentId);
		}
		if (validation.hasErrors()) {
			validation.keep();
			blockUserFromDepartment(departmentId);
		} else {
			User user = User.findById(userId);
			Date inDate = new Date();
			IdeaDeveloperBlockedFromDepartment toUnblock = IdeaDeveloperBlockedFromDepartment
					.find("Department_id = ? AND User_id = ?", departmentId,
							userId).first();
			toUnblock.delete();

			long organizationId = Long.parseLong(session.get("orgId"));
			Organization org = Organization.findById(organizationId);
			long orgLeadId = Long.parseLong(session.get("userId"));
			User orgLead = User.findById(orgLeadId);
			String action = "You have been unblocked by the Organization Lead "
					+ orgLead.nickName + " of Organization " + org.name
					+ " because: " + reason;
			Notification notif = new Notification(action, orgLead.nickName,
					user, inDate);
			notif.save();
			List<HasRoleInOrganization> allOrganizers = HasRoleInOrganization
					.find("Organization_id = ? AND Role_id = ?", org.id,
							(long) 2).fetch();
			for (int i = 0; i < allOrganizers.size(); i++) {
				HasRoleInOrganization organizerRole = allOrganizers.get(i);
				User organizer = organizerRole.user;
				if (organizer.notifyOnDepartment
						&& organizer.notifyOnOrganization) {
					action = "User " + user.nickName
							+ " have been unblocked by the Organization Lead "
							+ orgLead.nickName + " because: " + reason;
					Notification notifForOrganizer = new Notification(action,
							"System", organizer, inDate);
					notifForOrganizer.save();
				}

			}
			validation.addError("reason", "User Has Been Unblocked");
			validation.keep();
			blockUserFromDepartment(departmentId);
		}

	}

	/**
	 * Searches the database for an existence of an
	 * IdeaDeveloperBlockedFromDepartment which indicates that the user with
	 * this Id is blocked from the department with this Id.
	 * 
	 * @author Heba
	 * @param departmentId
	 *            Department ID
	 * @param userId
	 *            User ID
	 * @return - False if there is no IdeaDeveloperBlockedFromDepartment
	 *         instance in the data base. - TRUE if there is an
	 *         IdeaDeveloperBlockedFromDepartment instance in the data base.
	 */

	public static boolean isBlockedFromDepartment(long departmentId, long userId) {
		if (IdeaDeveloperBlockedFromDepartment.count(
				"Department_id = ? AND User_id = ?", departmentId, userId) == 1) {
			return true;
		} else {
			return false;
		}

	}

	/**
	 * @author noreen baraka
	 * @param org
	 * @return This method checks whether the organization is private
	 */

	public static boolean checkPrivate(Organization org) {
		if (org.type.equalsIgnoreCase("private")) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * @author noreen baraka
	 * @return This method checks if the user is authorized to view an
	 *         organization when it's private
	 */

	public static boolean isAuthorized() {
		long userId = Long.parseLong(session.get("userId"));
		long organizationId = Long.parseLong(session.get("orgId"));
		if (HasRoleInOrganization.count("User_id = ? AND Organization_id = ?",
				userId, organizationId) == 1) {
			return true;
		}
		return false;
	}

	/**
	 * 
	 * Takes the organization Id that is sent from orgList.html and retrieve the
	 * Organization from the database by ID. put the organization Id in a
	 * session to represent the current organization that is being navigated.
	 * renders the organization to its view.
	 * 
	 * @author Heba
	 * @param id
	 */
	public static void showOrg(long id) {
		Organization org = Organization.findById(id);
		session.put("orgId", id);
		org.views++;
		org.save();
		boolean isOrgLead = roleIsOrgLead();
		boolean isAuthorized = true;
		if (checkPrivate(org)) {
			isAuthorized = isAuthorized();
		}
		long userId =Long.parseLong(session.get("userId"));
		User user = User.findById(userId);
		boolean isFollowing = org.isFollowing(user);
		render(org, isOrgLead, isAuthorized, isFollowing);
	}

	public static void addRelation() {
		long orgId = Long.parseLong(session.get("orgId"));
		Organization org = Organization.findById(orgId);
		render(org);
	}

	/**
	 * @author mostafahammad
	 * @param relation
	 *            As an organization lead to create new relation in the
	 *            department
	 */
	public static void createRelation(
			@Required(message = "PLease Enter the Relation Name") String relation) {
		if (validation.hasErrors()) {
			validation.keep();
			addRelation();
		}
		if (Relation.count("relation = ?", relation) == 1) {
			validation.addError("relation", "Relation is Already exist!!");
			validation.keep();
			params.flash();
			addRelation();
		}
		Relation newRelation = new Relation(relation);
		newRelation.save();
		long orgId = Long.parseLong(session.get("orgId"));
		Organization org = Organization.findById(orgId);
		org.addRelation(newRelation);
		org.save();
		List<HasRoleInOrganization> allOrgLeads = HasRoleInOrganization.find(
				"Organization_id = ? AND Role_Id = ?", orgId, (long) 1).fetch();
		long userId = Long.parseLong(session.get("userId"));
		User orgLead = User.findById(userId);
		for (int i = 0; i < allOrgLeads.size(); i++) {
			User toNotify = allOrgLeads.get(i).user;
			if (toNotify.notifyOnOrganization) {
				String action = "Organization Lead " + orgLead.nickName
						+ " created relation " + newRelation.relation
						+ " in organization " + org.name;
				Notification notif = new Notification(action, "System",
						toNotify, new Date());
				notif.save();
			}
		}
		validation.addError("relation", "Relation is created!!");
		validation.keep();
		params.flash();
		long id = Long.parseLong(session.get("userId"));
		User user = User.findById(id);
		String action = "created Relation" + newRelation.relation;
		Logging log = new Logging(user, action, new Date());
		log.save();
		addRelation();
	}

	public static void search() {
		if (session.get("userId") != null) {
			long id = Long.parseLong(session.get("userId"));
			User user = User.findById(id);
			render(user);
		} else {
			validation.addError("email", "Please Login First");
			validation.keep();
			index();
		}
	}

	/**
	 * 
	 * @author Patrick Micheal
	 * 
	 * 
	 *         this method render's the quick search, and makes sure users are
	 *         logged in before Accessing the quick search page.
	 * 
	 */

	public static void quickSearch() {
		if (session.get("userId") != null) {
			long id = Long.parseLong(session.get("userId"));
			User user = User.findById(id);
			render(user);
		} else {
			validation.addError("email", "Please Login First");
			validation.keep();
			index();
		}
	}

	/**
	 * 
	 * @author Patrick Micheal
	 * @param search
	 *            allow user to filter search by organization, topic or
	 *            department
	 * @param name
	 *            user's input
	 * 
	 *            this method performs the quick search operation
	 *            "search by organization, topic or departments". making sure
	 *            users enter a valid search input.
	 * 
	 **/
	public static void simpleSearch(String search,
			@Required(message = "Please enter your search") String name) {
		if (validation.hasErrors()) {
			validation.keep();
			quickSearch();
		}

		if (search.equals("Organizations")) {

			String orgLike = "%" + name + "%";
			List<Organization> orgs = Organization.find("name like ?", orgLike)
					.fetch();
			render(orgs);
		}

		if (search.equals("Topics")) {

			String TopicLike = "%" + name + "%";
			List<Topic> Topics = Topic.find("title like ?", TopicLike).fetch();
			render(Topics);
		}

		if (search.equals("Departments")) {
			String DepartmentLike = "%" + name + "%";
			List<Department> Departments = Department.find("name like ?",
					DepartmentLike).fetch();
			render(Departments);
		}
	}

	/**
	 * @author nada mohamed
	 * @param org
	 *            /* in this method I check if the organization is secret to
	 *            prevent it from appearing in the search results. i take as
	 *            input the organization and check it's type and if it is secret
	 *            return true and in the searchMethod will remove it from the
	 *            organizations list
	 */
	public static boolean checkSecret(Organization org) {
		if (org.type.equalsIgnoreCase("secret")) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * @author Mariam Aboul Seoud
	 * 
	 * @param organizationName
	 *            , refers to the organization name the user is searching for
	 * @param userName
	 *            , refers to the user name the user is searching for
	 * @param departmentName
	 *            , refers to the department name the user is searching for
	 * @param topic
	 *            , refers to the topic name the user is searching for
	 * @param Tday
	 *            , Tday,Tmonth and Tyear refer to the time a certain topic was
	 *            posted
	 * @param Tmonth
	 * @param Tyear
	 * @param sorting
	 *            , refers to the drop-down list, where the user can choose
	 *            "most viewed" or "least viewed"
	 * @param comboBox
	 *            , refers to the drop-down list, where the user can choose
	 *            "Organizations", "Users", "departments", or "Topics" in order
	 *            to retrieve the list
	 */
	/*
	 * This method takes the inputs the user entered in the advanced search
	 * fields. The user may enter in one or more text fields. The text entered,
	 * for example, organization name, will be taken and the method searches for
	 * any word looks like the word entered. The id of each search result will
	 * be added to the list. At the end the search results list will be viewed
	 * using the searchmthod.html file as the search results found.
	 */
	/*
	 * Sprint-2 The user enters in the text fields in order to search for a
	 * certain organization, a certain user, a certain department or a certain
	 * topic. The user will be able to choose whether he wants to have his
	 * search results sorted, whether in an ascending "most viewed" or
	 * descending "least viewed" way. These are the 2 if cases the method checks
	 * after retrieving a certain list. If the user chooses "most viewed", there
	 * is a nested loop, that checks each organiazation's views, and if it is
	 * greater than the one before it swaps them together, and so on. If the
	 * user chooses "least viewed", there is a nested loop, that checks each
	 * organiazation's views, and if it is less than the one before it swaps
	 * them together, and so on. The comboBox input, is a drop-down list, which
	 * has the options "organizations", "users", "topics" or "departments". If
	 * the user chooses one of them it retrieves the list of all organizations
	 * available on the system.
	 */
	public static void searchmethod(String organizationName, String userName,
			String departmentName, String topic, int Tday, int Tmonth,
			int Tyear, String sorting, String comboBox) {
		session.put("organizationName", organizationName);
		session.put("userName", userName);
		session.put("departmentName", departmentName);
		session.put("topic", topic);
		session.put("Tday", Tday);
		session.put("Tmonth", Tmonth);
		session.put("Tyear", Tyear);
		session.put("sorting", sorting);
		session.put("comboBox", comboBox);

		List<Organization> orgs = new ArrayList<Organization>();
		List<User> user = new ArrayList<User>();
		List<Department> deps = new ArrayList<Department>();
		List<Topic> topics = new ArrayList<Topic>();
		List<Topic> tDate = new ArrayList<Topic>();

		Date dt = new Date();
		if (Tday != 0 & Tmonth != 0 & Tyear != 0) {
			Calendar y = Calendar.getInstance();
			y.set(Tyear, Tmonth, Tday);
			dt = y.getTime();
		}
		String orgLike = "%" + organizationName + "%";
		String userLike = "%" + userName + "%";
		String depLike = "%" + departmentName + "%";
		String topicLike = "%" + topic + "%";
		String combo = "%" + comboBox + "%";

		if (!organizationName.isEmpty()) {

			orgs = Organization.find("name like ?", orgLike).fetch();

			if (sorting.contentEquals("ascending")) {
				Organization temp;
				int i;

				for (int j = 0; j < orgs.size() - 1; j++) {
					i = 0;
					while (i < orgs.size() - 1) {
						if (orgs.get(i + 1).views > orgs.get(i).views) {

							temp = orgs.get(i + 1);
							orgs.set(i + 1, orgs.get(i));
							orgs.set(i, temp);
						} else {
							i++;
						}
					}
				}
			}

			if (sorting.contentEquals("descending")) {
				Organization temp;
				int i;

				for (int j = 0; j < orgs.size() - 1; j++) {
					i = 0;
					while (i < orgs.size() - 1) {
						if (orgs.get(i + 1).views < orgs.get(i).views) {
							temp = orgs.get(i + 1);
							orgs.set(i + 1, orgs.get(i));
							orgs.set(i, temp);
						} else {
							i++;
						}
					}
				}
			}
		}

		if (!userName.isEmpty()) {

			user = User.find(
					"firstName like ? OR lastName LIKE ? OR nickName Like ?",
					userLike, userLike, userLike).fetch();

			if (sorting.contentEquals("ascending")) {
				User temp;
				int i;

				for (int j = 0; j < user.size() - 1; j++) {
					i = 0;
					while (i < user.size() - 1) {
						if (user.get(i + 1).views > user.get(i).views) {

							temp = user.get(i + 1);
							user.set(i + 1, user.get(i));
							user.set(i, temp);
						} else {
							i++;
						}
					}
				}
			}

			if (sorting.contentEquals("descending")) {
				User temp;
				int i;

				for (int j = 0; j < user.size() - 1; j++) {
					i = 0;
					while (i < user.size() - 1) {
						if (user.get(i + 1).views < user.get(i).views) {
							temp = user.get(i + 1);
							user.set(i + 1, user.get(i));
							user.set(i, temp);
						} else {
							i++;
						}
					}
				}
			}
		}
		if (!departmentName.isEmpty()) {
			deps = Department.find("name LIKE ?", depLike).fetch();

			if (sorting.contentEquals("ascending")) {
				Department temp;
				int i;

				for (int j = 0; j < deps.size() - 1; j++) {
					i = 0;
					while (i < deps.size() - 1) {
						if (deps.get(i + 1).views > deps.get(i).views) {

							temp = deps.get(i + 1);
							deps.set(i + 1, deps.get(i));
							deps.set(i, temp);
						} else {
							i++;
						}
					}
				}
			}

			if (sorting.contentEquals("descending")) {
				Department temp;
				int i;

				for (int j = 0; j < deps.size() - 1; j++) {
					i = 0;
					while (i < deps.size() - 1) {
						if (deps.get(i + 1).views < deps.get(i).views) {
							temp = deps.get(i + 1);
							deps.set(i + 1, deps.get(i));
							deps.set(i, temp);
						} else {
							i++;
						}
					}
				}
			}
		}
		if (!topic.isEmpty()) {
			topics = Topic.find("title LIKE ? ", topicLike).fetch();

			if (sorting.contentEquals("ascending")) {
				Topic temp;
				int i;

				for (int j = 0; j < topics.size() - 1; j++) {
					i = 0;
					while (i < topics.size() - 1) {
						if (topics.get(i + 1).views > topics.get(i).views) {

							temp = topics.get(i + 1);
							topics.set(i + 1, topics.get(i));
							topics.set(i, temp);
						} else {
							i++;
						}
					}
				}
			}

			if (sorting.contentEquals("descending")) {
				Topic temp;
				int i;

				for (int j = 0; j < topics.size() - 1; j++) {
					i = 0;
					while (i < topics.size() - 1) {
						if (topics.get(i + 1).views < topics.get(i).views) {
							temp = topics.get(i + 1);
							topics.set(i + 1, topics.get(i));
							topics.set(i, temp);
						} else {
							i++;
						}
					}
				}
			}
		}
		if (Tyear != 0 && Tmonth != 0 && Tday != 0) {
			tDate = Topic.find("pDate LIKE ?", dt).fetch();

		}
		if (!comboBox.isEmpty()) {

			if (comboBox.contentEquals("organizations")) {
				orgs = Organization.findAll();
			}
			if (comboBox.contentEquals("users")) {
				user = User.findAll();
			}
			if (comboBox.contentEquals("departments")) {
				deps = Department.findAll();
			}
			if (comboBox.contentEquals("topics")) {
				topics = Topic.findAll();
			}
		}
		for (int i = 0; i < orgs.size(); i++) {
			if (checkSecret(orgs.get(i))) {
				orgs.remove(i);
			}
		}

		render(orgs, user, deps, topics, tDate);
	}

	public static void ShowOrganizations() {
		if (session.get("userId") != null) {
			long id = Long.parseLong(session.get("userId"));
			User user = User.findById(id);
			render(user);
		} else {
			validation.addError("email", "Please Login First");
			validation.keep();
			index();
		}
		List<Organization> organizations = Organization.findAll();
		if (!organizations.isEmpty())
			render(organizations);
		else
			render();
	}

	/**
	 * It checks whether the user requesting the administration area is an
	 * administrator or not, if an administrator it sends to the CRUD module
	 * implementation that administrates all entities in the system.
	 * 
	 * @author Shady
	 * 
	 * @param email
	 *            Required String
	 * @param password
	 *            Required String
	 */
	public static void isAdmin(
			@Required(message = "Please Enter Your E-mail !!") @Email(message = "Please Enter a Valid e-mail !!") String email,
			@Required(message = "Password is required !!") String password) {
		if (validation.hasErrors()) {
			params.flash();
			validation.keep();
			adminLogin();
		}
		if (User.isValidLogin(email, password)) {
			User user = User.connect(email, password);
			if (user.isAdmin) {
				render();
			} else {
				validation.addError("email", "Invalid Admin Login");
				validation.keep();
				adminLogin();
			}
		} else {
			validation.addError("email", "Invalid Login");
			validation.keep();
			adminLogin();
		}
	}

	/**
	 * It takes the user signUp information from signUp.html form. Then creates
	 * a new user if the email is not registered in the system and with all
	 * valid inputs.
	 * 
	 * @author Shady
	 * 
	 * @param firstName
	 *            Required String
	 * @param lastName
	 *            Required String
	 * @param nName
	 *            Required String
	 * @param email
	 *            Required, Email String
	 * @param password
	 *            Required String
	 * @param confirmPw
	 *            Required String
	 * @param day
	 *            int
	 * @param month
	 *            int
	 * @param year
	 *            int
	 * @param no
	 *            int
	 * @param st
	 *            String
	 * @param city
	 *            String
	 * @param pro
	 *            String
	 * @param country
	 *            String
	 */
	public static void addUser(
			@Required(message = "Please Enter Your First Name") String firstName,
			@Required(message = "Please Enter Your Last Name") String lastName,
			@Required(message = "Please Enter Your Nickname") String nName,
			@Required(message = "Please Enter Your E-mail") @Email(message = "Please Enter a Valid e-mail") String email,
			@Required(message = "Password is required") String password,
			@Required(message = "Confirm Password") String confirmPw, int day,
			int month, int year, String no, String st, String city, String pro,
			String country, Blob profilePicture) {
		validation.equals(confirmPw, password).message(
				"Password Should be Confirmed");
		if (validation.hasErrors()) {
			params.flash();
			validation.keep();
			signUp();
		}
		if (User.isExist(email)) {
			validation.addError("email", "This e-mail is already registered");
			params.flash();
			validation.keep();
			signUp();
		}
		Date dt = new Date();
		if (day != 0 & month != 0 & year != 0) {
			Calendar y = Calendar.getInstance();
			y.set(year, month, day);
			dt = y.getTime();
		}
		String add = no + " " + st + " - " + city + " - " + pro + ", "
				+ country + ".";
		User newUser = new User(email, password, firstName, lastName, nName,
				country, dt, add);
		newUser.profilePicture = profilePicture;
		newUser.save();

		if (Invitation.count("email = ?", email) == 1) {
			Invitation inv = Invitation.find("email = ?", email).first();
			// Role role = new Role("Organizer");
			Department dep = Department.findById(inv.depId);
			requestOrganizer(newUser.id, dep.id);
			// OrganizerInOrganization org=new OrganizerInOrganization(newUser,
			// role, dep);
			// org.save();
		}
		String action = "Signed Up";
		Logging log = new Logging(newUser, action, new Date());
		log.save();
		session.put("userId", newUser.id);
		viewProfile();
	}

	/**
	 * It renders the editUserInformation.html form from user profile.
	 * 
	 * @author Shady
	 */
	public static void editUserInformation() {
		long userId = Long.parseLong(session.get("userId"));
		User user = User.findById(userId);
		render(user);
	}

	/**
	 * It takes the edited informations from the form and calls the method
	 * updateUser in the user class that overwrite the old entries with the news
	 * one.
	 * 
	 * @author Shady
	 * @param firstName
	 *            Required String
	 * @param lastName
	 *            Required String
	 * @param nickName
	 *            Required String
	 * @param email
	 *            Required, Email String
	 * @param password
	 *            Required String
	 * @param confirmPw
	 *            Required String
	 * @param day
	 *            int
	 * @param month
	 *            int
	 * @param year
	 *            int
	 * @param no
	 *            int
	 * @param st
	 *            String
	 * @param city
	 *            String
	 * @param pro
	 *            String
	 * @param country
	 *            String
	 */
	public static void updateUserInformation(
			@Required(message = "Please Enter Your First Name") String firstName,
			@Required(message = "Please Enter Your Last Name") String lastName,
			@Required(message = "Please Enter Your Nickname") String nickName,
			@Required(message = "Please Enter Your E-mail") @Email(message = "Please Enter a Valid e-mail") String email,
			@Required(message = "Password is required") String password,
			@Required(message = "Confirm Password") String confirmPw, int day,
			int month, int year, String no, String st, String city, String pro,
			String country) {
		validation.equals(confirmPw, password).message(
				"Password Should be Confirmed");
		if (validation.hasErrors()) {
			params.flash();
			validation.keep();
			signUp();
		}
		if (User.isExist(email)) {
			validation.addError("email", "This e-mail is already registered");
			params.flash();
			validation.keep();
			signUp();
		}
		Date dt = new Date();
		if (day != 0 & month != 0 & year != 0) {
			Calendar y = Calendar.getInstance();
			y.set(year, month, day);
			dt = y.getTime();
		}
		String add = no + " " + st + " - " + city + " - " + pro + ", "
				+ country + ".";
		long id = Long.parseLong(session.get("userId"));
		User user = User.findById(id);
		user.updateUser(email, password, firstName, lastName, nickName,
				country, dt, add);
		viewProfile();
	}

	/**
	 * It is being called by viewProfil() after checking if the user is logged
	 * in or not.
	 * 
	 * @author Shady
	 * 
	 * @param id
	 *            long User ID
	 */
	public static void Profile(long id) {
		User user = User.findById(id);
		String randomID = Codec.UUID();
		List<Notification> notifications = Notification
				.retrieveNotificationsOfAUser(id);
		int newNotifications = 0;
		for (int i = 0; i < notifications.size(); i++) {
			if (!(notifications.get(i).viewed)) {
				newNotifications++;
			}
		}
		render(user, randomID, notifications, newNotifications);
	}

	/**
	 * It checks the session for the userId if it is there then the user is
	 * logged in and pass his/her id to the profile(id) to view the profile else
	 * it render the index asking to login first.
	 * 
	 * @author Shady
	 */
	public static void viewProfile() {
		if (session.get("userId") != null) {
			long id = Long.parseLong(session.get("userId"));
			Profile(id);
		} else {
			validation.addError("email", "Please Login First");
			validation.keep();
			index();
		}
	}

	/**
	 * from the profile the user calls this method to render all the
	 * organizations s/he contributed in
	 * 
	 * @author Shady
	 */
	public static void myOrganization() {
		long userId = Long.parseLong(session.get("userId"));
		User user = User.findById(userId);
		List<HasRoleInOrganization> x = HasRoleInOrganization.find(
				"User_id = ?", userId).fetch();
		List<Organization> orgs = new ArrayList<Organization>();
		for (int i = 0; i < x.size(); i++) {
			orgs.add(x.get(i).organization);
		}
		render(orgs, user);
	}

	/**
	 * It takes the email and password then check the database for the user
	 * matching the params if found login and save the user id in session to be
	 * accessible later on.
	 * 
	 * @author Shady
	 * 
	 * @param email
	 *            String
	 * @param password
	 *            String
	 * 
	 */
	public static void logIn(
			@Required(message = "Please Enter Your E-mail !!") @Email(message = "Please Enter a Valid e-mail !!") String email,
			@Required(message = "Password is required !!") String password) {
		if (validation.hasErrors()) {
			params.flash();
			validation.keep();
			index();
		}
		if (User.isValidLogin(email, password)) {
			User user = User.connect(email, password);
			session.put("userId", user.id);
			String action = "Logged In";
			Logging log = new Logging(user, action, new Date());
			log.save();
			viewProfile();
		} else {

			validation.addError("email", "Invalid Login");
			validation.keep();
			index();
		}
	}

	/**
	 * It removes the user id from the session and log him/her out.
	 * 
	 * @author Shady
	 */
	public static void logout() {
		if (session.get("userId") != null) {
			long id = Long.parseLong(session.get("userId"));
			session.remove("userId");
			User user = User.findById(id);
			String action = "Logged Out";
			Logging log = new Logging(user, action, new Date());
			log.save();
			Application.index();
		} else {
			validation.addError("email", "Please Login First");
			validation.keep();
			index();
		}

	}

	/**
	 * It takes the user email retrieve the User from the database by ID then
	 * sends an email with the User password to the email.
	 * 
	 * @author Shady
	 * 
	 * @param email
	 *            Required String
	 * 
	 * @throws EmailException
	 */
	public static void sendPassword(
			@Required(message = "Please Enter Your E-mail") @Email(message = "Please Enter a Valid e-mail") String email)
			throws EmailException {
		if (validation.hasErrors()) {
			params.flash();
			validation.keep();
			getPassword();
		}
		if (!User.isExist(email)) {
			validation.addError("email", "This e-mail is not registered");
			params.flash();
			validation.keep();
			getPassword();
		}
		User user = User.find("email = ?", email).first();
		String pw = user.password;

		SimpleEmail mail = new SimpleEmail();
		mail.setHostName("smtp.gmail.com");
		mail.setSmtpPort(587);
		mail.setAuthenticator(new DefaultAuthenticator(
				"Sharesoft.WebDevelopment", "sharesoft-11"));
		mail.setTLS(true);
		mail.setFrom("Sharesoft.WebDevelopment@gmail.com");
		mail.addTo(email);
		mail.setSubject("Hello " + user.nickName
				+ "!! Here is Your Password!! ");
		mail.setMsg("Dear " + user.nickName
				+ ", As you requsted your password,"
				+ "\n Here is Your Password: " + pw);
		mail.send();
		validation.addError("email", "Your password has been sent!!");
		params.flash();
		validation.keep();
		getPassword();
	}

	/*
	 * @author Omar Eissa
	 * 
	 * @param email
	 * 
	 * @param departmentId
	 * 
	 * @output this method adds the unregistered user to themodel invitations to
	 * be later checked when the user signs up
	 */
	/*
	 * Sending Invitation to an unregistered user to make him an organizer
	 */
	public static void sendingInvites(
			@Required(message = "Please Enter Your E-mail !!") @Email(message = "Please Enter a Valid e-mail !!") String email,
			long depId) throws EmailException {
		if (validation.hasErrors()) {
			params.flash();
			validation.keep();
			inviteOrganizer(depId);
		}
		if (User.isExist(email)) {
			validation
					.addError("email",
							"this user is already registered , please invite unregistered user");
			params.flash();
			validation.keep();
			inviteOrganizer(depId);
		} else {
			SimpleEmail mail = new SimpleEmail();
			mail.setHostName("smtp.gmail.com");
			mail.setSmtpPort(587);
			mail.setAuthenticator(new DefaultAuthenticator(
					"Sharesoft.WebDevelopment", "sharesoft-11"));
			mail.setTLS(true);
			mail.setFrom("Sharesoft.WebDevelopment@gmail.com");
			mail.addTo(email);
			mail.setSubject("Sharesoft Organizer Invitation!!");
			mail.setMsg("You Are Invited to Be an Organizer in ShareSoft\n"
					+ "Http://localhost:9000");
			mail.send();
			Invitation inv = new Invitation(email, depId);
			inv.save();
			validation.addError("email", "Request Sent!!");
			validation.keep();
			inviteOrganizer(depId);
		}
	}

	/*
	 * @author Omar Eissa
	 * 
	 * @param userId from the session
	 * 
	 * @output List of requests
	 */
	/*
	 * This method displays the list of requests related to the user
	 */
	public static void viewRequests() {
		long userId = Long.parseLong(session.get("userId"));
		// User user = User.findById(userId);
		List<Request> requests = Request.find("User_id = ?", userId).fetch();
		render(requests);
	}

	/*
	 * @author Omar Eissa
	 * 
	 * @param requestId
	 */
	/*
	 * This method calls another method viewOrganizerReq and give ittwo
	 * parameters the requestId and the depId that is in the samerow as the
	 * requestid in table requests
	 */
	public static void checkRequest(long reqId) {
		Request req = Request.findById(reqId);
		String action = req.request;
		if (action.equalsIgnoreCase("be organizer")) {
			long depId = Long.parseLong(req.propId);
			viewOrganizerReq(depId, reqId);
		}
		if (action.contains("Added topic")) {
			long depId = Long.parseLong(req.propId);
			viewTopicRequest(reqId, depId);
		}

	}

	/*
	 * @author Omar Eissa
	 * 
	 * @param departmentId
	 * 
	 * @param requestId
	 * 
	 * @output department
	 */
	/*
	 * This method views the selected request for the user to accept or reject
	 */
	public static void viewOrganizerReq(long depId, long reqId) {
		Department dep = Department.findById(depId);
		render(dep, reqId);
	}

	/*
	 * @author Omar Eissa
	 * 
	 * @param departmentId
	 * 
	 * @param requestId
	 * 
	 * @param userId from the session
	 */
	/*
	 * This method add the user as an organizer to the department
	 */
	public static void acceptOrganizaerRequest(long depId, long reqId) {
		Department dep = Department.findById(depId);
		long userId = Long.parseLong(session.get("userId"));
		User user = User.findById(userId);
		long roleId = 2;
		Role role = Role.findById(roleId);
		OrganizerInOrganization x = new OrganizerInOrganization(user, role, dep);
		x.save();
		Request.delete("id = ?", reqId);
	}

	/*
	 * @author Omar Eissa
	 * 
	 * @param requestId
	 */
	/*
	 * This method deletes the request from the model so that it cannot be
	 * displayed in the future as the user rejected it
	 */
	public static void rejectOrganizaerRequest(long reqId) {
		Request.delete("id = ?", reqId);
	}

	public static void inviteOrganizer(long depId) {
		long orgId = Long.parseLong(session.get("orgId"));
		Organization org = Organization.findById(orgId);
		List<User> users = User.findAll();
		Department dep = Department.findById(depId);
		for (int i = 0; i < users.size(); i++) {
			if (HasRoleInOrganization.count(
					"User_id = ? AND Organization_id = ?", users.get(i), orgId) == 1) {
				users.remove(i);
			} else {
				if (OrganizerInOrganization.count(
						"User_id = ? AND Department_id = ?", users.get(i),
						depId) == 1) {
					users.remove(i);
				}
			}
		}
		render(dep, users, org);
	}

	public static void requestOrganizer(long userId, long depId) {
		User user = User.findById(userId);
		String action = "be organizer";
		String propId = "" + depId + "";
		Request req = new Request(user, action, propId);
		req.save();
		validation.addError("invited", "Request Sent!!");
		validation.keep();
		inviteOrganizer(depId);
	}

	/**
	 * @author Nada mohamed in this method i browse all tags to the user
	 */
	public static void tags() {
		List<Tag> tags = Tag.findAll();
		render(tags);
	}

	/**
	 * @author Hussien
	 * @param tag
	 *            A String contain tags that the user enter
	 * @param tId
	 *            To be able to identify the Topic
	 * @param dId
	 *            To be able to identify the Department that have the Topic
	 * 
	 *            In this method user can tag topic freely. After the user add
	 *            the Topic i check if this topic has entered before, if yes i
	 *            didn'd added to the database add tell the user that this idea
	 *            had entered before otherwise we added in the database. We also
	 *            check for the validation if the user didn't type anything in
	 *            the and then press request a message well appear "Please Enter
	 *            something to TAG".
	 */
	// and
	/**
	 * @author Kareem Lala Starting from the (Date date = new Date();) line this
	 *         part is supposed to send a notification to the owner of the topic
	 *         notifying him that there was an update that occured in his topic
	 */
	public static void tagTopic(
			@Required(message = "Please Enter something to TAG") String tag,
			long tId, long dId) {
		Topic top = Topic.findById(tId);
		if (validation.hasErrors()) {
			validation.keep();
			addTopicTag(tId, dId);
		}
		if (Tag.count("tag = ?", tag) == 1) {
			Tag newTag = Tag.find("tag = ?", tag).first();
			List<Tag> topTags = top.tag;
			for (int i = 0; i < topTags.size(); i++) {
				if (topTags.get(i).getId() == newTag.getId()) {
					validation.addError("tag",
							"This Topic is Already tagged with this!!");
					validation.keep();
					addTopicTag(tId, dId);
				}
			}
			top.addTag(newTag);
			top.save();
			long id = Long.parseLong(session.get("userId"));
			User user = User.findById(id);
			List<User> toNotifyUsers = top.toBeNotified;
			for (int j = 0; j < toNotifyUsers.size(); j++) {
				User toNotify = toNotifyUsers.get(j);
				if (toNotify.notifyOnTopic) {
					String action = "Topic  " + top.title + " tagged "
							+ newTag.tag + " by user " + user.nickName;
					Notification notif = new Notification(action, "System",
							toNotify, new Date());
					notif.save();
				}
			}
			toNotifyUsers = newTag.toBeNotified;
			for (int j = 0; j < toNotifyUsers.size(); j++) {
				User toNotify = toNotifyUsers.get(j);
				if (toNotify.notifyOnTopic) {
					String action = "Topic  " + top.title + " tagged "
							+ newTag.tag + " by user " + user.nickName;
					Notification notif = new Notification(action, "System",
							toNotify, new Date());
					notif.save();
				}
			}
			validation.addError("tag", "Tagged Successfully!!");
			validation.keep();
			String action = "Tagged Topic " + top.title + " With Tag "
					+ newTag.tag;
			Logging log = new Logging(user, action, new Date());
			log.save();
			addTopicTag(tId, dId);

		} else {
			Tag newTag = new Tag(tag);
			newTag.save();
			top.addTag(newTag);
			top.save();
			long id = Long.parseLong(session.get("userId"));
			User user = User.findById(id);
			List<User> toNotifyUsers = top.toBeNotified;
			for (int j = 0; j < toNotifyUsers.size(); j++) {
				User toNotify = toNotifyUsers.get(j);
				if (toNotify.notifyOnTopic) {
					String action = "Topic  " + top.title + " tagged "
							+ newTag.tag + " by user " + user.nickName;
					Notification notif = new Notification(action, "System",
							toNotify, new Date());
					notif.save();
				}
			}
			validation.addError("tag", "Tagged Successfully!!");
			validation.keep();
			String action = "Tagged Topic " + top.title + " With Tag "
					+ newTag.tag;
			Logging log = new Logging(user, action, new Date());
			log.save();
			addTopicTag(tId, dId);
			Date date = new Date();
			long senderId = Long.parseLong(session.get("userId"));
			User sender = User.findById(senderId);
			String senderNickName = sender.nickName;
			long topicId = Long.parseLong(session.get("topicId"));
			Topic topic = Topic.find("topic", topicId).first();
			User receiver = User.findById(topic.user);
			Notification notification = new Notification(
					"An Update has occured!", "Update done by: "
							+ senderNickName, receiver, date);
			notification.save();

		}

	}

	/**
	 * @author Hussien
	 * @param ideaId
	 *            To be able to identify the Idea that belongs to a Topic
	 * @param tId
	 *            To be able to identify the Topic that contains Ideas
	 * @param dId
	 *            To be able to identify the Department that have the Topic
	 * 
	 *            I search for the topicId, departmentId, and ideaId and then
	 *            call the addIdeaTag in view
	 */
	public static void addIdeaTag(long ideaId, long tId, long dId) {
		long id = Long.parseLong(session.get("orgId"));
		Organization org = Organization.findById(id);
		Topic top = Topic.findById(tId);
		Department dep = Department.findById(dId);
		Idea idea = Idea.findById(ideaId);
		render(top, dep, idea, org);
	}

	/**
	 * @author Hussien
	 * @param tag
	 *            A String contain tags that the user enter
	 * @param tId
	 *            To be able to identify the Topic that contains Ideas
	 * @param dId
	 *            To be able to identify the Department that have the Topic
	 * @param idea
	 *            To be able to identify the Idea that belongs to a Topic
	 * 
	 *            As a user, i can only tag my idea. After the user add the Idea
	 *            i check if this idea has entered before, if yes i didn'd added
	 *            to the database add tell the user that this idea had entered
	 *            before otherwise we added in the database. We also check for
	 *            the validation if the user didn't type anything in the and
	 *            then press request a message well appear. One more thing, when
	 *            user view ideas, only his idea are followed by link tag so he
	 *            can tag his idea only
	 */
	// and
	/**
	 * @author Kareem Lala Starting from the (Date date = new Date();)line this
	 *         part is supposed to send a notification to the owner of the idea
	 *         notifying him that there was an update that occured in his
	 *         created idea
	 */

	public static void tagIdea(
			@Required(message = "Please Enter something to TAG") String tag,
			long tId, long dId, long idea) {
		Idea curIdea = Idea.findById(idea);
		if (validation.hasErrors()) {
			validation.keep();
			addIdeaTag(idea, tId, dId);
		}
		if (Tag.count("tag = ?", tag) == 1) {
			Tag newTag = Tag.find("tag = ?", tag).first();
			List<Tag> ideaTags = curIdea.tag;
			for (int i = 0; i < ideaTags.size(); i++) {
				if (ideaTags.get(i).getId() == newTag.getId()) {
					validation.addError("tag",
							"This Topic is Already tagged with this!!");
					validation.keep();
					addIdeaTag(idea, tId, dId);
				}
			}
			curIdea.addTag(newTag);
			long id = Long.parseLong(session.get("userId"));
			User user = User.findById(id);
			boolean isBeingNotified = false;
			for (int i = 0; i < newTag.toBeNotified.size(); i++) {
				if (newTag.toBeNotified.get(i).id == user.id) {
					isBeingNotified = true;
				}
			}
			if (!isBeingNotified) {
				newTag.toBeNotified.add(user);
				newTag.save();
			}
			curIdea.save();
			List<User> toNotifyUsers = curIdea.toBeNotified;
			for (int j = 0; j < toNotifyUsers.size(); j++) {
				User toNotify = toNotifyUsers.get(j);
				if (toNotify.notifyOnIdea) {
					String action = "Idea  " + curIdea.title + " tagged "
							+ newTag.tag + " by user " + user.nickName;
					Notification notif = new Notification(action, "System",
							toNotify, new Date());
					notif.save();
				}
			}
			validation.addError("tag", "Tagged Successfully!!");
			validation.keep();
			String action = "Tagged His/Her Idea With Tag " + newTag.tag;
			Logging log = new Logging(user, action, new Date());
			log.save();
			addIdeaTag(idea, tId, dId);
		} else {
			Tag newTag = new Tag(tag);
			newTag.save();
			curIdea.addTag(newTag);
			curIdea.save();
			long id = Long.parseLong(session.get("userId"));
			User user = User.findById(id);
			newTag.toBeNotified.add(user);
			newTag.save();
			List<User> toNotifyUsers = curIdea.toBeNotified;
			for (int j = 0; j < toNotifyUsers.size(); j++) {
				User toNotify = toNotifyUsers.get(j);
				if (toNotify.notifyOnIdea) {
					String action = "Idea  " + curIdea.title + " tagged "
							+ newTag.tag + " by user " + user.nickName;
					Notification notif = new Notification(action, "System",
							toNotify, new Date());
					notif.save();
				}
			}
			validation.addError("tag", "Tagged Successfully!!");
			validation.keep();
			String action = "Tagged His/Her Idea With Tag " + newTag.tag;
			Logging log = new Logging(user, action, new Date());
			log.save();
			addIdeaTag(idea, tId, dId);
			Date date = new Date();
			long senderId = Long.parseLong(session.get("userId"));
			User sender = User.findById(senderId);
			String senderNickName = sender.nickName;
			long ideaId = Long.parseLong(session.get("topicId"));
			Idea ideax = Idea.find("idea", ideaId).first();
			User receiver = User.findById(ideax.author);
			Notification notification = new Notification(
					"An Update has occured!", "Update done by: "
							+ senderNickName, receiver, date);
			notification.save();
		}

	}

	/**
	 * @author Hussien
	 * @param tId
	 *            To be able to identify the Topic that belongs to specific
	 *            Department
	 * @param dId
	 *            To be able to identify the Department that have the topic
	 * 
	 *            I search for the topicId, departmentId, and then call the
	 *            addIdeaTag in view
	 */

	public static void addTopicTag(long tId, long dId) {
		long id = Long.parseLong(session.get("orgId"));
		Organization org = Organization.findById(id);
		Topic top = Topic.findById(tId);
		Department dep = Department.findById(dId);
		render(top, dep, org);
	}

	/**
	 * @author Hussien
	 * @param depId
	 *            To be able to identify the Department that have the topic that
	 *            will be requested
	 * 
	 *            A list of organizers and the department i belong to then call
	 *            the view HTML
	 */
	public static void requestTopic(long depId) {
		long orgId = Long.parseLong(session.get("orgId"));
		Organization org = Organization.findById(orgId);
		List<User> users = User.findAll();
		Department dep = Department.findById(depId);
		for (int i = 0; i < users.size(); i++) {
			if (HasRoleInOrganization.count(
					"User_id = ? AND Organization_id = ?", users.get(i), orgId) == 1) {
				users.remove(i);
			} else {
				if (OrganizerInOrganization.count(
						"User_id = ? AND Department_id = ?", users.get(i),
						depId) == 1) {
					users.remove(i);
				}
			}
		}
		render(dep, users, org);
	}

	/**
	 * @author Hussien
	 * @param depId
	 *            To be able to identify the Department
	 * @param topic
	 *            A String contain Topic that the user enter
	 * 
	 *            The request belong to the specific departmentId
	 */
	public static void requestToAddTopic(long depId, String topic) {
		long id = Long.parseLong(session.get("orgId"));
		Organization org = Organization.findById(id);
		long userId = Long.parseLong(session.get("userId"));
		User user = User.findById(userId);
		String action = "Added topic: " + topic;
		String propId = "" + depId + "";
		Request req = new Request(user, action, propId);
		req.save();
		render(org);
	}

	/**
	 * @author Hussien
	 * @param requestId
	 *            The request ID that send to the organizers and organization
	 *            lead
	 * @param departmentId
	 *            The department ID which is belong to specific organization
	 * 
	 *            Get a list of requests and department i belong to and then
	 *            call the HTML
	 */
	public static void viewTopicRequest(long requestId, long departmentId) {
		Request request = Request.findById(requestId);
		Department department = Department.findById(departmentId);
		String topicName = request.request.substring(13);
		render(requestId, topicName, department);
	}

	/**
	 * @author Hussien
	 * @param requestId
	 *            The request ID that send to the organizers and organization
	 *            lead
	 * 
	 *            When approving the request, the organizers create a new topics
	 *            by calling method creatTopicUponRequest and then delete the
	 *            requested link as it is now useless
	 */
	public static void approveTopicRequest(long requestId) {
		Request request = Request.findById(requestId);
		String topicName = request.request.substring(13);
		long departmentId = Long.parseLong(request.propId);
		Request.delete("id = ?", requestId);
		creatTopicUponRequest(departmentId, topicName);
	}

	/**
	 * @author Hussien
	 * @param requestId
	 *            The request ID that send to the organizers and organization
	 *            lead
	 * 
	 *            When the topic is rejected, the requested link is deleted
	 */
	public static void rejectTopicRequest(long requestId) {
		Request.delete("id = ?", requestId);
		viewRequests();
	}

	/**
	 * @author Hussien
	 * @param departmentId
	 *            The department ID which is belong to specific organization
	 * @param topicName
	 *            The topic name that has been requested
	 * 
	 *            This method create a new topic which is belong to specific
	 *            department and organization
	 */
	public static void creatTopicUponRequest(long departmentId, String topicName) {
		long id = Long.parseLong(session.get("orgId"));
		Organization org = Organization.findById(id);
		Department dep = Department.findById(departmentId);
		render(dep, org, topicName);
	}

	// @author Mohamed Medhat Shafei
	// @param invitation
	// @throws EmailException
	// This method Sends invitation to invite unregistered users
	// Check first if the validation has errors, I send the parameter and keeps
	// the validation for
	// the next iteration. Then check if the user who is supposed to be invited
	// already existing,
	// if yes, an error is added, if no, then the mail is sent after setting the
	// subject and the body
	// of it and sending it to the parameter String invitation which represents
	// the email.

	// I find the user by the id, create an object from logging (which is the
	// table),
	// and insert the user who performs the action, the action, and the date.

	public static void sendInv(
			@Required(message = "Please Enter Your E-mail !!") @Email(message = "Please Enter a Valid e-mail !!") String invitation)
			throws EmailException {
		long id = Long.parseLong(session.get("userId"));
		if (validation.hasErrors()) {
			params.flash();
			validation.keep();
			Profile(id);
		}
		if (User.isExist(invitation)) {
			validation
					.addError("invitation",
							"this user is already registered , please invite unregistered user");
			params.flash();
			validation.keep();
			Profile(id);
		} else {

			SimpleEmail mail = new SimpleEmail();
			mail.setHostName("smtp.gmail.com");
			mail.setSmtpPort(587);
			mail.setAuthenticator(new DefaultAuthenticator(
					"Sharesoft.WebDevelopment", "sharesoft-11"));
			mail.setTLS(true);
			mail.setFrom("Sharesoft.WebDevelopment@gmail.com");
			mail.addTo(invitation);
			mail.setSubject("Invitation!!!");
			mail.setMsg("You are invited to join ShareSoft by ");
			mail.send();
			params.flash();
			validation.addError("invitation", "The Invitation is sent!!");
			validation.keep();
			long uId = Long.parseLong(session.get("userId"));
			User user = User.findById(uId);
			String action = "invited his/her friend";
			Logging log = new Logging(user, action, new Date());
			log.save();
			Profile(id);
		}
	}

	public static void viewAllDepartments() {
		long id = Long.parseLong(session.get("orgId"));
		Organization org = Organization.findById(id);
		List<Department> deps = org.department;
		render(deps, org);
	}

	public static void relation(boolean x) {
		render(x);
	}

	public static void relations(Department department, Department department2,
			String relation) {
		String s = session.get("orgId");
		long l = Long.parseLong(s);
		Organization org = Organization.findById(l);

		String dep = "%" + department + "%";
		String dep2 = "%" + department2 + "%";

		Department y = Department.find("Department=?", dep).first();
		Department z = Department.find("Department=?", dep2).first();

		if (y == z) {
			relation(true);
		}

		else {
			render(relation);

		}

	}

	public static void viewDepartment(long id) {
		long orgId = Long.parseLong(session.get("orgId"));

		long userId = Long.parseLong(session.get("userId"));
		// User u = User.findById(uid);
		Organization org = Organization.findById(orgId);
		Department dep = Department.findById(id);
		dep.views++;
		int z = dep.topicCompare(id);
		// Role r=Role.findById(2);
		// if(OrganizerInOrganization.find
		// ("User = ?,Role = ?,Department = ?",u,r,dep)!=null)
		// {
		// dep.topicCompare(dep.topics);
		// }
		boolean isBlocked = isBlockedFromDepartment(id, userId);
		boolean isOrgLead = roleIsOrgLead();
		boolean isOrganizer = roleIsOrganizer(id);
		User user = User.findById(userId);
		boolean isFollowing = org.isFollowing(user);
		render(dep, isOrgLead, org, z, isOrganizer, isBlocked, isFollowing);
	}

	public static void viewAllTopics(long dId) {
		long id = Long.parseLong(session.get("orgId"));
		Organization org = Organization.findById(id);
		Department dep = Department.findById(dId);
		List<Topic> topics = dep.topics;
		render(topics, dep, org);
	}

	public static void viewTopic(long tId, long dId) {
		long id = Long.parseLong(session.get("orgId"));
		Organization org = Organization.findById(id);
		Topic top = Topic.findById(tId);
		Department dep = Department.findById(dId);
		long curUser = Long.parseLong(session.get("userId"));
		render(top, dep, curUser, org);
	}

	public static void viewTopicById(long topId) {
		List<Department> deps = Department.findAll();
		for (int i = 0; i < deps.size(); i++) {
			Department curDep = Department.findById(deps.get(i).getId());
			List<Topic> tops = curDep.topics;
			for (int j = 0; j < tops.size(); j++) {
				if (tops.get(j).getId() == topId) {
					showTopic(topId, deps.get(i).id);
				}
			}
		}
	}

	/**
	 * @author Kareem Lala
	 * @param tId
	 *            Topic ID
	 * @param dId
	 *            Department ID This method shows the relations between the
	 *            topics inside the department
	 */

	public static void RelationBetweenTopics(long tId, long dId) {
		long id = Long.parseLong(session.get("orgId"));
		Organization org = Organization.findById(id);
		Department dep = Department.findById(dId);
		List<Topic> topics = dep.topics;
		for (int i = 0; i < topics.size(); i++) {
			if (topics.get(i).id == tId) {
				topics.remove(i);
			}
		}
		render(topics, tId, dId, dep, org);
	}

	/**
	 * @author Kareem Lala
	 * @param currentId
	 * @param toSetId
	 * @param depId
	 *            The purpose of this method is to set the relation between
	 *            topics through taking in the current topic's ID and the ID of
	 *            the topic to have a relation with, also this method includes
	 *            the part which notifies the owners of the topics with any
	 *            updates which happen to their topics
	 */
	public static void setRelationbetweenTopics(long currentId, long toSetId,
			long depId,
			@Required(message = "Relation is Required") String relation) {
		if (validation.hasErrors()) {
			validation.keep();
			RelationBetweenTopics(currentId, depId);
		}
		Topic current = Topic.findById(currentId);
		Topic toSet = Topic.findById(toSetId);
		if (current.isLocked == true && toSet.isLocked == true) {
			validation
					.addError("set",
							"The relation can't be created because both topics are locked");
			validation.keep();
			RelationBetweenTopics(currentId, depId);

		} else if (toSet.isLocked == true) {
			validation.addError("set",
					"The relation can't be created because Topic "
							+ toSet.title + "is locked.");
			validation.keep();
			RelationBetweenTopics(currentId, depId);

		} else {
			if (current.isLocked == true) {
				validation.addError("set",
						"The relation can't be created because Topic "
								+ current.title + "is locked.");
				validation.keep();
				RelationBetweenTopics(currentId, depId);
			}
		}
		RelationsBetweenTopic x = new RelationsBetweenTopic(current, toSet,
				relation);
		x.save();
		List<User> toNotifyUsers = current.toBeNotified;
		for (int j = 0; j < toNotifyUsers.size(); j++) {
			User toNotify = toNotifyUsers.get(j);
			if (toNotify.notifyOnTopic) {
				String action = "Topic: " + current.title
						+ " related to topic :" + toSet.title + " AS "
						+ x.relation;
				Notification notif = new Notification(action, "System",
						toNotify, new Date());
				notif.save();
			}
		}
		validation.addError("relation", "Relation Set Successfully!!");
		validation.keep();
		long id = Long.parseLong(session.get("userId"));
		User user = User.findById(id);
		String action = "Added Relation " + relation + "between Topic "
				+ current.title + " and " + toSet.title;
		Logging log = new Logging(user, action, new Date());
		log.save();
		RelationBetweenTopics(currentId, depId);
	}

	/**
	 * @author Daniel Riad
	 * 
	 * @param title
	 *            : this is needed as a parameter in order to set the title of
	 *            the department to this.
	 * @param Description
	 *            : this is needed as a parameter in order to set the
	 *            description of the department to this. This method simply
	 *            takes as parameters the title and description of a department,
	 *            and creates a department in the organization chosen.
	 */
	public static void createDepartment(@Required String title,
			@Required String description, boolean lock) {
		if (roleIsOrgLead()) {
			long id = Long.parseLong(session.get("orgId"));
			Organization org = Organization.findById(id);
			if (validation.hasErrors()) {
				validation.keep();
				createDepartmentView();
			}
			Department department = new Department(title, description);
			if (lock) {
				department.isLocked = true;
			}
			long uId = Long.parseLong(session.get("userId"));
			User user = User.findById(uId);
			department.toBeNotified.add(user);
			department.save();
			org.addDepartment(department);
			String action = "Created Department " + department.name;
			Logging log = new Logging(user, action, new Date());
			log.save();
			org.save();
			List<User> toNotifyUsers = org.toBeNotified;
			for (int j = 0; j < toNotifyUsers.size(); j++) {
				User toNotify = toNotifyUsers.get(j);
				if (toNotify.notifyOnOrganization) {
					action = "Department  " + department.name
							+ " was created in Organization " + org.name
							+ " by user " + user.nickName;
					Notification notif = new Notification(action, "System",
							toNotify, new Date());
					notif.save();
				}
			}
			validation.addError("description", "Department Created!!");
			validation.keep();
			createDepartmentView();

		}

	}

	/**
	 * @author Daniel Riad
	 * @param This
	 *            method just renders the createDepartmentView
	 * 
	 */
	public static void createDepartmentView() {
		long id = Long.parseLong(session.get("orgId"));
		Organization org = Organization.findById(id);
		render(org);
	}

	/**
	 * @author Daniel
	 * @param This
	 *            method doesn't take parameters, and it checks whether the
	 *            logged in user's role is Organization lead or not, and returns
	 *            a boolean whether he is an organization lead or not.
	 * 
	 */
	public static boolean roleIsOrgLead() {

		long userId = Long.parseLong(session.get("userId"));
		long orgId = Long.parseLong(session.get("orgId"));
		HasRoleInOrganization x = HasRoleInOrganization.find(
				"User_id = ? AND Organization_id = ?", userId, orgId).first();
		if (x == null) {
			return false;
		} else {
			Role r = x.role;
			String s = r.role;
			if (s.equals("Organization Lead")) {
				return true;

			} else {
				return false;
			}
		}

	}

	/**
	 * @author Daniel Riad
	 * @param this method simply gets the chosen Organization's ID, gets it from
	 *        the database, and then renders the view changeType and passes the
	 *        organization as a parameter.
	 */
	public static void changeType() {

		long id = Long.parseLong(session.get("orgId"));
		Organization org = Organization.findById(id);

		render(org);

		return;

	}

	/**
	 * 
	 * @param type
	 *            : to set the type of the organization to this.
	 * @author Daniel Riad This simply sets the type of a certain organization
	 *         to the type given in the parameters.
	 */
	public static void setType(@Required String type, boolean tagable) {
		if (roleIsOrgLead()) {
			if (validation.hasErrors()) {
				validation.keep();
				changeType();
			}
			long id = Long.parseLong(session.get("orgId"));
			Organization org = Organization.findById(id);
			org.tagable = tagable;
			org.save();
			org.type = type;
			org.save();
			long uId = Long.parseLong(session.get("userId"));
			User user = User.findById(uId);
			String action = "Set organization type to " + type;
			Logging log = new Logging(user, action, new Date());
			log.save();
			List<User> toNotifyUsers = org.toBeNotified;
			for (int j = 0; j < toNotifyUsers.size(); j++) {
				User toNotify = toNotifyUsers.get(j);
				if (toNotify.notifyOnOrganization) {
					action = "Organization  " + org.name + " was set to "
							+ type + " organization by organization lead "
							+ user.nickName;
					Notification notif = new Notification(action, "System",
							toNotify, new Date());
					notif.save();
				}
			}

			validation.addError("type", "Type Changed!!");
			validation.keep();
			changeType();
		}
	}

	/**
	 * @author Daniel Riad
	 * @param depId
	 *            : This is the Id of the department of which i want to check if
	 *            the user is an organizer in.
	 * @return This method returns true or false depending on whether the User
	 *         who is currently logged in is an organizer in the department, of
	 *         which the Id is passed in the parameter.
	 */
	public static boolean roleIsOrganizer(long depId) {

		long userId = Long.parseLong(session.get("userId"));
		OrganizerInOrganization x = OrganizerInOrganization.find(
				"User_id = ? AND Department_id = ?", userId, depId).first();
		if (x == null) {
			return false;
		} else {
			Role r = x.role;
			String s = r.role;
			if (s.equals("Organizer")) {
				return true;

			} else {
				return false;
			}
		}

	}

	public static void createTag() {
		long organizationId = Long.parseLong(session.get("orgId"));
		Organization org = Organization.findById(organizationId);
		render(org);
	}

	public static void doCreateTag(
			@Required(message = "PLease Enter Tag Name") String tag) {
		if (validation.hasErrors()) {
			validation.keep();
			createTag();
		} else {
			if (Tag.count("tag = ?", tag) > 0) {
				validation.addError("tag", "Tag Already Exist");
				validation.keep();
				createTag();
			} else {
				Tag newTag = new Tag(tag);
				newTag.save();
				long orgId = Long.parseLong(session.get("orgId"));
				Organization organization = Organization.findById(orgId);
				long userId = Long.parseLong(session.get("userId"));
				User user = User.findById(userId);
				newTag.toBeNotified.add(user);
				newTag.save();
				List<User> toNotifyUsers = organization.toBeNotified;
				for (int j = 0; j < toNotifyUsers.size(); j++) {
					User toNotify = toNotifyUsers.get(j);
					if (toNotify.notifyOnOrganization) {
						String action = "User " + user.nickName
								+ " created tag " + newTag.tag
								+ " in organization " + organization.name;
						Notification notif = new Notification(action, "System",
								toNotify, new Date());
						notif.save();
					}
				}

				validation.addError("tag", "Tag Created Successfully");
				validation.keep();
				createTag();
			}
		}
	}

	/**
	 * 
	 * @author emam
	 * @params titel to add the titel of the topic on the DB
	 * @params describtion to add the describtion of the topic on the DB
	 * @params author to identify the author of the topic
	 */
	/*
	 * the method used for add topic to the DB
	 */

	public static void addTopic(@Required String titel,
			@Required String describtion, long depId, boolean locked) {
		if (validation.hasErrors()) {
			validation.keep();
			Topic(depId);
		}
		long id = Long.parseLong(session.get("userId"));
		User user = User.findById(id);
		Department dep = Department.findById(depId);
		Topic T = new Topic(user, titel, describtion);
		T.toBeNotified.add(user);
		if (locked) {
			T.isLocked = true;
		}
		T.save();
		dep.addTopic(T);
		dep.save();
		user.communityContribution = user.communityContribution + 2;
		user.save();
		long orgId = Long.parseLong(session.get("orgId"));
		addRole(id, (long) 3, orgId);
		String action = "Add topic " + T.title + "to department " + dep.name;
		Logging log = new Logging(user, action, new Date());
		log.save();
		List<User> toNotifyUsers = dep.toBeNotified;
		for (int j = 0; j < toNotifyUsers.size(); j++) {
			User toNotify = toNotifyUsers.get(j);
			if (toNotify.notifyOnDepartment) {
				action = "Topic  " + T.title + " was created in department "
						+ dep.name + " by user " + user.nickName;
				Notification notif = new Notification(action, "System",
						toNotify, new Date());
				notif.save();
			}
		}

		validation.addError("describtion", "Topic Added!!");
		validation.keep();
		Topic(depId);

	}

	/**
	 * 
	 * @author emam
	 * @params d this the idea that will be reported
	 */
	/*
	 * the method task is to add 1 in the report column in the DB when ever the
	 * button report is clicked
	 */
	public static void Report(Idea d) {
		d.reportIdea(true);
		d.save();
		render();
	}

	/**
	 * @author noreen baraka
	 * @param searchOrganization
	 * @param itemName
	 *            this method searches within an organization for topics or
	 *            departments according to the user choice from the drop down
	 *            list in the html
	 */
	public static void organizationSearch(String searchOrganization,
			String itemName) {

		long orgId = Long.parseLong(session.get("orgId"));
		Organization organ = Organization.findById(orgId);

		if (searchOrganization.equals("Topics")) {
			List<Topic> topicResults = new ArrayList();
			List<Department> deps = organ.department;
			for (int i = 0; i < deps.size(); i++) {
				Department dep = deps.get(i);

				List<Topic> topics = dep.topics;
				for (int j = 0; j < topics.size(); j++) {
					Topic top = topics.get(j);
					if (top.title.contains(itemName)) {
						topicResults.add(top);
					}
				}
			}
			render(topicResults);
		} else {
			if (searchOrganization.equals("Departments")) {
				List<Department> depResults = new ArrayList();
				List<Department> deps = organ.department;
				for (int i = 0; i < deps.size(); i++) {
					if (deps.get(i).name.contains(itemName)) {
						depResults.add(deps.get(i));
					}
				}
				render(depResults);
			}
		}
	}

	/**
	 * @author mostafahammad
	 * @param depId
	 *            this method renders all the relations found in this
	 *            department.
	 */
	public static void manageRelations(long depId) {
		long id = Long.parseLong(session.get("orgId"));
		Organization org = Organization.findById(id);
		Department dep = Department.findById(depId);
		List<RelationsBetweenDepartment> relations = RelationsBetweenDepartment
				.find("Department1_id = ?", depId).fetch();
		render(dep, relations, org);
	}

	/**
	 * @author mostafahammad
	 * @param relId
	 * @param depId
	 *            this methods deletes the relation created by the organization
	 *            lead.
	 * 
	 */
	public static void deleteRelation(long relId, long depId) {
		RelationsBetweenDepartment rel = RelationsBetweenDepartment
				.findById(relId);
		List<User> toNotifyUsers = rel.department1.toBeNotified;
		for (int j = 0; j < toNotifyUsers.size(); j++) {
			User toNotify = toNotifyUsers.get(j);
			if (toNotify.notifyOnDepartment) {
				String action = "Department " + rel.department1.name
						+ " is no longer" + rel.relation.relation
						+ "department " + rel.department2.name;
				Notification notif = new Notification(action, "System",
						toNotify, new Date());
				notif.save();
			}
		}
		rel.delete();
		manageRelations(depId);
	}

	/**
	 * @author Daniel Riad
	 * @param depId
	 *            : this is the chosen department's ID This method simply takes
	 *            the chosen department's id, and gets the list of departments
	 *            in the chosen organization, and removes the chosen department
	 *            from them in order to set a relation with it, and also puts
	 *            the list of all relations available in the organization in a
	 *            list.
	 */
	/**
	 * @author mostafahammad
	 * @param relId
	 *            I added the relId param to this method so that if it is called
	 *            from manageRelation method it renders the relId to the HTML
	 *            view.
	 */

	public static void setRelationBetweenDepartments(long depId, long relId) {
		long id = Long.parseLong(session.get("orgId"));
		Organization org = Organization.findById(id);
		List<Department> orgDeps = org.department;
		for (int i = 0; i < orgDeps.size(); i++) {
			if (orgDeps.get(i).getId() == depId) {
				orgDeps.remove(i);
			}

		}
		Department dep = Department.findById(depId);
		List<Relation> orgRelations = org.relation;
		render(orgDeps, orgRelations, dep, org, relId);

	}

	/**
	 * @author Daniel Riad
	 * @param currentId
	 *            :this is the chosen department's id.
	 * @param depToSetId
	 *            : this is the other department's id.
	 * @param RelationToSetId
	 *            : this is the relation's id. This method takes in the current
	 *            chosen Orgnization's id, the department to be chosen's Id, and
	 *            the the Relation's id, and defines a relationship between
	 *            those two departments.
	 * 
	 */
	/**
	 * @author mostafahammad
	 * @param relId
	 *            it takes the relId from the view and if it's not equals to
	 *            zerothen this method was called from the view that was called
	 *            from manageRelation method thus it deletes the old relation
	 *            and create another with the edited values.
	 */
	// and
	/**
	 * @author Kareem Lala (starting from the Date date = new Date() line) this
	 *         part is supposed to notify the organizer of the updates that
	 *         occured in his department
	 */

	public static void addRelationBetweenDepartments(long currentId,
			long depToSetId, long RelationToSetId, long relId) {
		if (relId != 0) {
			RelationsBetweenDepartment rel = RelationsBetweenDepartment
					.findById(relId);
			rel.delete();
		}
		if (RelationToSetId == 0 || depToSetId == 0) {
			validation.addError("set", "Please Enter The Missing value.");
			validation.keep();
			setRelationBetweenDepartments(currentId, relId);
		}
		if (RelationsBetweenDepartment
				.count("Department1_id = ? AND Department2_id = ? AND Relation_id = ?",
						currentId, depToSetId, RelationToSetId) == 1) {
			validation.addError("set", "The Relation is Already defined.");
			validation.keep();
			setRelationBetweenDepartments(currentId, relId);
		}

		Department cur = Department.findById(currentId);
		Department toSet = Department.findById(depToSetId);
		if (cur.isLocked == true && toSet.isLocked == true) {
			validation
					.addError("set",
							"The relation can't be created because both departments are locked");
			validation.keep();
			setRelationBetweenDepartments(currentId, relId);

		} else if (toSet.isLocked == true) {
			validation.addError("set",
					"The relation can't be created because Department "
							+ toSet.name + " is locked.");
			validation.keep();
			setRelationBetweenDepartments(currentId, relId);

		} else {
			if (cur.isLocked == true) {
				validation.addError("set",
						"The relation can't be created because Department "
								+ cur.name + " is locked.");
				validation.keep();
				setRelationBetweenDepartments(currentId, relId);
			}
		}
		Relation relation = Relation.findById(RelationToSetId);
		RelationsBetweenDepartment newRelation = new RelationsBetweenDepartment(
				cur, toSet, relation);
		newRelation.save();
		long uId = Long.parseLong(session.get("userId"));
		User user = User.findById(uId);
		String action = "Set " + cur.name + " " + relation.relation + " "
				+ toSet.name;
		Logging log = new Logging(user, action, new Date());
		log.save();
		List<User> toNotifyUsers = newRelation.department1.toBeNotified;
		for (int j = 0; j < toNotifyUsers.size(); j++) {
			User toNotify = toNotifyUsers.get(j);
			if (toNotify.notifyOnDepartment) {
				action = "Department " + newRelation.department1.name
						+ " is set " + newRelation.relation.relation
						+ "department " + newRelation.department2.name;
				Notification notif = new Notification(action, "System",
						toNotify, new Date());
				notif.save();
			}
		}
		validation.addError("set", "The Relation defined successfully.");
		validation.keep();
		setRelationBetweenDepartments(currentId, relId);

		Date date = new Date();
		long senderId = Long.parseLong(session.get("userId"));
		User sender = User.findById(senderId);
		String senderNickName = sender.nickName;
		long depID = Long.parseLong(session.get("depId"));
		OrganizerInOrganization orgInOrg = OrganizerInOrganization.find(
				"Department_id", depID).first();
		User receiver = User.findById(orgInOrg.user);
		Notification notification = new Notification("An Update has occured!",
				"Update done by: " + senderNickName, receiver, date);
		notification.save();

	}

	// @author Mohamed Medhat Shafei
	// This method views all the logs that are saved. A list of logs that carry
	// logging
	// (logging is the name of the table created which contains User user,
	// String action, and Date inDate),
	// then list is rendered to be viewed.
	// In each method that performs an action that should logged. I find the
	// user by the id,
	// create an object from logging (which is the table), and insert the user
	// who performs the action,
	// the action, and the date.

	public static void viewLog() {
		List<Logging> log = Logging.findAll();
		long id = Long.parseLong(session.get("orgId"));
		Organization org = Organization.findById(id);
		render(log, org);
	}

	/**
	 * 
	 * @author Salma youssef
	 * @params the name of the new organization to add this name on the DB
	 * @params the type of the new Organization to add this type on the DB
	 */
	/*
	 * the method used for Create new Organization and to add to the DB
	 */

	public static void createNewOrganization(
			@Required(message = "Please Enter Organization Name") String newName,
			String newType) {
		if (validation.hasErrors()) {
			validation.keep();
			createOrganization();
		}
		if (Organization.count("name = ? ", newName) == 1) {
			validation
					.addError("newName",
							"Organization with same name already exists, Please Enter another name");
			validation.keep();
			createOrganization();
		}
		Organization org = new Organization(newName, newType);
		org.save();

		validation.addError("newName", "Organization " + newName + " Created");
		validation.keep();
		long roleId = 1;
		long userId = Long.parseLong(session.get("userId"));
		if (addRole(userId, roleId, org.id)) {
			createOrganization();
		}

	}

	public static void createOrganization() {
		render();

	}

	public static void viewMyTopics() {
		long userId = Long.parseLong(session.get("userId"));
		User user = User.findById(userId);
		List<Topic> topics = Topic.find("user.id = ?", userId).fetch();
		render(topics, user);
	}

	public static void viewMyIdeas() {
		long userId = Long.parseLong(session.get("userId"));
		User user = User.findById(userId);
		List<Idea> ideas = Idea.find("author.id = ?", userId).fetch();
		render(ideas, user);
	}

	/**
	 * @author Ahmed Abou Samra
	 * @param organizationName
	 * @param userName
	 * @param userRole
	 * @param departmentName
	 * @param topic
	 * @param Tday
	 * @param Tmonth
	 * @param Tyear
	 */
	/*
	 * this method exports search results to a file into CSV format and takes
	 * the input from the session
	 */

	public static void export() throws IOException {

		String organizationName = session.get("organizationName");
		session.remove("organizationName");
		String userName = session.get("userName");
		session.remove("userName");
		String departmentName = session.get("departmentName");
		session.remove("departmentName");
		String topic = session.get("topic");
		session.remove("topic");
		int Tday = Integer.parseInt(session.get("Tday"));
		session.remove("Tday");
		int Tmonth = Integer.parseInt(session.get("Tmonth"));
		session.remove("Tmonth");
		int Tyear = Integer.parseInt(session.get("Tyear"));
		session.remove("Tyear");
		List<Organization> orgs = new ArrayList<Organization>();
		List<User> user = new ArrayList<User>();
		List<Department> deps = new ArrayList<Department>();
		List<Topic> topics = new ArrayList<Topic>();
		List<Topic> tDate = new ArrayList<Topic>();
		Date dt = new Date();
		if (Tday != 0 & Tmonth != 0 & Tyear != 0) {
			Calendar y = Calendar.getInstance();
			y.set(Tyear, Tmonth, Tday);
			dt = y.getTime();
		}
		String orgLike = "%" + organizationName + "%";
		String userLike = "%" + userName + "%";
		String depLike = "%" + departmentName + "%";
		String topicLike = "%" + topic + "%";

		if (!organizationName.isEmpty()) {

			orgs = Organization.find("name like ?", orgLike).fetch();
		}
		if (!userName.isEmpty()) {

			user = User.find(
					"firstName like ? OR lastName LIKE ? OR nickName Like ?",
					userLike, userLike, userLike).fetch();
		}
		if (!departmentName.isEmpty()) {
			deps = Department.find("name LIKE ?", depLike).fetch();
		}
		if (!topics.isEmpty()) {
			topics = Topic.find("title LIKE ?", topicLike).fetch();
		}
		if (Tyear != 0 && Tmonth != 0 && Tday != 0) {
			tDate = Topic.find("pDate LIKE ?", dt).fetch();

		}

		for (int i = 0; i < orgs.size(); i++) {
			if (checkSecret(orgs.get(i))) {
				orgs.remove(i);
			}
		}
		FileWriter f = new FileWriter(new File("results.txt"));
		int i = 0;
		if (!orgs.isEmpty()) {
			f.write("Organizations:");
			while (i < orgs.size()) {
				f.write(orgs.get(i).name);
				f.write(",");
				i++;
			}
		}
		i = 0;
		if (!deps.isEmpty()) {
			f.write("Departments:");
			while (i < deps.size()) {
				f.write(deps.get(i).name);
				f.write(",");
				i++;
			}
		}

		i = 0;
		if (!user.isEmpty()) {
			f.write("Users:");
			while (i < user.size()) {
				f.write(user.get(i).nickName);
				f.write(",");
				i++;
			}
		}

		i = 0;
		if (!topics.isEmpty()) {
			f.write("Topics:");
			while (i < topics.size()) {
				f.write(topics.get(i).title);
				f.write(",");
				i++;
			}
		}

		f.close();
		render();
	}

	/**
	 * @author Ahmed Abou Samra
	 * @param ideaId
	 */
	/*
	 * This method takes the ideaId and routes it to the share page to share it
	 */
	public static void share(long ideaId) {
		long id = Long.parseLong(session.get("orgId"));
		Organization org = Organization.findById(id);
		render(ideaId, org);
	}

	/**
	 * @author Ahmed Abou Samra
	 * @param ideaId
	 * @param email
	 * @throws EmailException
	 */
	/*
	 * This method takes the ideaId and the email to send the idea to the user
	 * of the email to share it with him
	 */
	public static void shareIdea(long ideaId, String email)
			throws EmailException {
		SimpleEmail mail = new SimpleEmail();
		mail.setHostName("smtp.gmail.com");
		mail.setSmtpPort(587);
		mail.setAuthenticator(new DefaultAuthenticator(
				"Sharesoft.WebDevelopment", "sharesoft-11"));
		mail.setTLS(true);
		mail.setFrom("Sharesoft.WebDevelopment@gmail.com");
		mail.addTo(email);
		mail.setSubject("Sharesoft");
		Idea idea = Idea.findById(ideaId);
		mail.setMsg("" + idea.content);
		mail.send();
		validation.addError("", "");
		validation.keep();
	}

	/**
	 * @author Khalid Osama
	 * @param email
	 * @param dep
	 * 
	 * @throws EmailException
	 */
	public static void inviteIdeaDevelopers(String email, Department dep)
			throws EmailException {
		SimpleEmail mail = new SimpleEmail();
		mail.setHostName("smtp.gmail.com");
		mail.setSmtpPort(587);
		mail.setAuthenticator(new DefaultAuthenticator(
				"Sharesoft.WebDevelopment", "sharesoft-11"));
		mail.setTLS(true);
		mail.setFrom("Sharesoft.WebDevelopment@gmail.com");
		mail.addTo(email);
		mail.setSubject("Sharesoft");

		mail.setMsg("You have been invited to join" + dep.name);
		mail.send();
		validation.addError("", "");
		validation.keep();

	}

	/**
	 * It takes the user, role, and organization IDs to add the new trenary
	 * relation between the User, Organization, and Role in
	 * HasRoleInOrganization Model. If the user has no role in this organization
	 * it creates the new role and saves it, if the role was with ID '1' which
	 * means Organization Lead it deletes any other Idea Developer and Organizer
	 * relation roles. if the user has the same role in the same organization it
	 * does not add it.
	 * 
	 * @author Shady
	 * 
	 * @param userId
	 *            long User ID
	 * @param roleId
	 *            long Role ID
	 * @param orgId
	 *            long Organization ID
	 * 
	 * @return True if the relation added successfully in HasRoleInOrganization
	 *         Model, False otherwise
	 */
	public static boolean addRole(long userId, long roleId, long orgId) {

		if (roleId == 3 || roleId == 2) {
			if (HasRoleInOrganization.count(
					"User_id = ? AND Role_id = ? AND Organization_id = ?",
					userId, (long) 1, orgId) == 1) {
				return false;
			}
		}
		if (!(HasRoleInOrganization.count(
				"User_id = ? AND Role_id = ? AND Organization_id = ?", userId,
				roleId, orgId) == 1)) {
			if (roleId == 1) {
				HasRoleInOrganization organizerRole = HasRoleInOrganization
						.find("User_id = ? AND Role_id = ? AND Organization_id = ?",
								userId, (long) 2, orgId).first();
				HasRoleInOrganization ideaDeveloperRole = HasRoleInOrganization
						.find("User_id = ? AND Role_id = ? AND Organization_id = ?",
								userId, (long) 3, orgId).first();
				if (organizerRole != null) {
					organizerRole.delete();
				}
				if (ideaDeveloperRole != null) {
					ideaDeveloperRole.delete();
				}
			}
			User user = User.findById(userId);
			Organization org = Organization.findById(orgId);
			Role role = Role.findById(roleId);
			HasRoleInOrganization roleInOrg = new HasRoleInOrganization(user,
					role, org);
			roleInOrg.save();
			boolean isBeingNotified = false;
			for (int i = 0; i < org.toBeNotified.size(); i++) {
				if (org.toBeNotified.get(i).id == user.id) {
					isBeingNotified = true;
				}
			}
			if (!isBeingNotified) {
				org.toBeNotified.add(user);
				org.save();
			}
			return true;
		}
		return false;
	}

	/**
	 * @author Ahmed El-Sherif
	 * @param tid
	 * @param did
	 */
	public static void createIdea(Long tid, Long did) {
		Department d = Department.findById(did);
		Topic t = Topic.findById(tid);
		render(t, d);
	}

	/**
	 * this method is the one that actually creates the idea
	 * and adds it into the topic and notifies the author about it
	 * @author Ahmed El-Sherif
	 * @param tid topic id
	 * @param did department id
	 * @param content 
	 * @param title
	 * @param draft
	 */

	public static void ideaCreated(long tid, long did,
			@Required String content, @Required String title, int draft) {
		if (validation.hasErrors()) {
			if (content.length() == 0 && title.length() == 0)
				flash.error("please write a title and content!");
			else if (content.length() == 0)
				flash.error("please write a content!");
			else
				flash.error("please write a titlez!");

			createIdea(tid, did);
		}
		Topic t = Topic.findById(tid);
		Department d = Department.findById(did);
		long uid = Long.parseLong(session.get("userId"));
		User u = User.findById(uid);

		if (draft == 1) {
			Idea i = new Idea(u, title, content).save();
			i.toBeNotified.add(u);
			i.save();
			t.ideas.add(i);
			t.lastactivity = new Date();
			t.save();
			u.communityContribution = u.communityContribution + 3;
			u.save();
			List<User> toNotifyUsers = t.toBeNotified;
			for (int j = 0; j < toNotifyUsers.size(); j++) {
				User toNotify = toNotifyUsers.get(j);
				if (toNotify.notifyOnTopic) {
					String action = "Idea  " + i.title + " was added to topic "
							+ t.title + " by user " + u.nickName;
					Notification notif = new Notification(action, "System",
							toNotify, new Date());
					notif.save();
				}
			}

			ideaView(i.id, tid, did);

		} else {
			Draft f = new Draft(title, content, t, d).save();
			u.draft.add(f);
			u.save();
			draftList();
		}
	}
	
	/**
	 * to get to this method use the hyperlink in the view profile.html
	 * called my drafts 
	 * this method gets the users drafts and shows them to him
	 * in the view draftList.html
	 * @author Ahmed El-Sherif
	 * @param none
	 */

	public static void draftList() {
		Long uid = Long.parseLong(session.get("userId"));
		User u = User.findById(uid);
		List<Draft> drafts = u.draft;
		render(drafts);
	}
	
	/**
	 * you get to this method by clicking the hyper link of your draft 
	 * in the view draftList.html
	 * this method calls the view draftView.html
	 * to actually show the user his draft
	 * @param fid draft id
	 */

	public static void draftView(Long fid) {
		Draft f = Draft.findById(fid);
		render(f);
	}
	/**
	 * this method publishes the draft by making a new idea by the same
	 * arguments as the draft's then deleting the draft 
	 * @author Ahmed El-Sherif
	 * @param fid draft id
	 */

	public static void publishDraft(Long fid) {
		Long uid = Long.parseLong(session.get("userId"));
		User u = User.findById(uid);
		Draft f = Draft.findById(fid);
		ideaCreated(f.topic.id, f.department.id, f.content, f.title, 1);
		u.draft.remove(f);
		f.delete();
	}

	public static void showTopic(Long tid, Long did) {
		session.put("topicId", tid);
		session.put("departmentId", did);
		Long ui = Long.parseLong(session.get("userId"));
		User user = User.findById(ui);
		boolean roleIsIdeaDeveloper = roleIsIdeaDeveloper();
		Topic t = Topic.findById(tid);
		t.views++;
		t.save();
		boolean isFollowing = t.isFollowing(user);
		Department d = Department.findById(did);
		boolean isBlocked = isBlockedFromTopic(tid, ui);
		boolean roleIsOrganizer = roleIsOrganizer(ui);
		render(t, d, user, roleIsIdeaDeveloper, roleIsOrganizer, isBlocked, isFollowing);
	}

	/**
	 * @author noreen baraka
	 * @param rate
	 * @param ideaId
	 * @param departmentId
	 * @param topicId
	 *            This method enables the user to rate an idea when viewing it
	 */

	public static void rateIdea(int rate, long ideaId, long departmentId,
			long topicId) {
		long userId = Long.parseLong(session.get("userId"));
		Idea idea = Idea.findById(ideaId);
		idea.rate.add(rate);
		idea.userRated.add(userId);
		idea.save();
		ideaView(ideaId, topicId, departmentId);

	}

	/**
	 * @author noreen baraka
	 * @param userId
	 * @param ideaId
	 * @return This method checks if the user rated the idea before in order to
	 *         disable rating if he did
	 */

	public static boolean ratedBefore(long userId, long ideaId) {
		Idea idea = Idea.findById(ideaId);
		ArrayList<Long> userRated = idea.userRated;
		boolean flag = false;
		for (int i = 0; i < userRated.size(); i++) {
			if (userId == userRated.get(i)) {
				flag = true;
			}
		}
		return flag;
	}

	public static void ideaView(Long iid, Long tid, Long did) {
		Long userId = Long.parseLong(session.get("userId"));
		session.put("ii", iid);
		Idea i = Idea.findById(iid);
		i.views++;
		i.save();
		Department d = Department.findById(did);
		Topic t = Topic.findById(tid);
		boolean ratedBef = ratedBefore(userId, iid);
		render(i, t, d, userId, ratedBef);

	}

	public static void addComment(Long ideaId, Long tid, Long did,
			String content) {
		Long userId = Long.parseLong(session.get("userId"));
		User user = User.findById(userId);
		Idea idea = Idea.findById(ideaId);
		Comment c = new Comment(content, user).save();
		idea.comments.add(c);
		idea.idealastactivity = new Date();
		idea.save();
		List<User> toNotifyUsers = idea.toBeNotified;
		for (int j = 0; j < toNotifyUsers.size(); j++) {
			User toNotify = toNotifyUsers.get(j);
			if (toNotify.notifyOnIdea) {
				String action = "User " + user.nickName + " Commented "
						+ content + " on Idea " + idea.title;
				Notification notif = new Notification(action, "System",
						toNotify, new Date());
				notif.save();
			}
		}

		user.communityContribution++;
		user.save();
		ideaView(ideaId, tid, did);

	}

   /**
    * 
    * this method deletes the idea from inside the view ideaView.html it self
    * using a button that is visible only to the idea's author
    * @author Ahmed El-Sherif
    * @param ideaId
    * @param tid topic id
    * @param did department id
    */
	public static void deleteIdea(Long ideaId, Long tid, Long did) {
		Idea ii = Idea.findById(ideaId);
		Topic t = Topic.findById(tid);
		t.ideas.remove(ii);
		t.save();
		List<User> toNotifyUsers = t.toBeNotified;
		for (int j = 0; j < toNotifyUsers.size(); j++) {
			User toNotify = toNotifyUsers.get(j);
			if (toNotify.notifyOnTopic) {
				String action = "Idea  " + ii.title
						+ " was deleted from topic " + t.title;
				Notification notif = new Notification(action, "System",
						toNotify, new Date());
				notif.save();
			}
		}

		ii.delete();
		showTopic(tid, did);

	}

	/**
	 * @author Khaled Ramzy
	 */
	/*
	 * the method view the list of requested mirgs
	 */

	public static void requestedMirg() {
		List<RequestMirging> mirgingList = RequestMirging.findAll();
		boolean isIdeaDeveloper = roleIsIdeaDeveloper();
		render(mirgingList, isIdeaDeveloper);
	}

	/**
	 * @author Khaled Ramzy
	 * @param requestId
	 *            request Id
	 * @param proceed
	 *            integer value used to determin the action that will be taken
	 */
	/*
	 * The method impelement the request acceptance or request refuse
	 */

	public static void manageMirg(long requestId, int proceed) {
		System.out.println("we entered req.id= " + requestId);

		RequestMirging req = RequestMirging.findById(requestId);
		if (proceed == 1) {
			System.out.println("we entered action= " + proceed);

			long[] ideaIds = new long[req.ideas.size()];
			for (int k = 0; k < ideaIds.length; k++) {
				ideaIds[k] = req.ideas.get(k).id;
			}
			long topicId = req.topic;
			long departmentId = req.department;
			req.delete();
			ideaUpdate2(ideaIds, 6, topicId, departmentId, 0);
		} else if (proceed == 2) {
			System.out.println("we entered id= " + proceed);

			req.delete();
			requestedMirg();

		}
	}

	/**
	 * @authors Khaled Ramzy,Ahmed El-Sherif
	 * @param check
	 *            take the list of ideas that im going to perform action on it
	 * @param state
	 *            integer represent the action that will be taken.. each value
	 *            represent option in the DropDownList in showTopic.html if 1
	 *            ----> open if 2 ----> close if 3 ----> promote to execution if
	 *            4-----> hide if 5 ----> delete if 6 ----> merge if 7 ---->
	 *            request merge for idea developers
	 * @param topicId
	 *            topic id
	 * @param departmentId
	 *            department id
	 */
	/*
	 * the method taks array of ideas and performe action on it
	 */

	public static void ideaUpdate2(long[] check, int state, Long topicId,
			Long departmentId, long label) {

		Long tid = Long.parseLong(session.get("topicId"));
		Long did = Long.parseLong(session.get("departmentId"));
		Long uid = Long.parseLong(session.get("userId"));
		User user = User.findById(uid);
		

			if(state==0&&label!=0)
			{
				System.out.println("here");
				Label l=Label.findById(label);

				for (int k = 0; k < check.length; k++) {
					Idea i = Idea.findById(check[k]);
					IdeasInLabel il=new IdeasInLabel(i,tid,did,l.id).save();
					l.ideas.add(il);
					System.out.println("idea title"+ il.idea.title);

					l.save();
			}
				showTopic(tid, did);
			}

				
		
			
		
			else if(state!=0&&label==0){	
		if (state == 1 || state == 2 || state == 4||state==3) {
			for (int k = 0; k < check.length; k++) {
				
				if(state == 1 || state == 2 || state == 4)
				{	
				Idea i = Idea.findById(check[k]);
				Topic t=Topic.findById(tid);
				i.state = state;
				i.save();
				if(state==4)
				{
					List<User> toNotifyUsers = t.toBeNotified;
					for (int j = 0; j < toNotifyUsers.size(); j++) {
						User toNotify = toNotifyUsers.get(j);
						if (toNotify.notifyOnTopic) {
							String action = "Idea  " + i.title
									+ " was deleted from topic " + t.title;
							Notification notif = new Notification(action, "System",
									toNotify, new Date());
							notif.save();
							Notification notificationToAuthor=new Notification(action,"System",i.author,new Date());
							notificationToAuthor.save();
						}
					}
            
				}
				}
				  else if(state==3)
				  {
					  user.communityContribution = user.communityContribution + 10;
					  user.save();
					  Idea i=Idea.findById(check[k]);
					  i.state=state;
					  i.save();
					  Department department= Department.findById(did);
					  boolean exist=false;
					  for(int m=0;m<department.executionCenter.size();m++)
					  {
						  if(department.executionCenter.get(m).idea.id==i.id)
							  exist=true;
					  }
					  if(exist==true);
					  else
					  {
					  PromotedIdea pi=new PromotedIdea(i).save();
					  pi.users.add(i.author);
					  pi.save();
					  department.executionCenter.add(pi);
					  department.save();
					  }
				  }

			}

		} else if (state != 0 && label == 0) {
			if (state == 1 || state == 2 || state == 4 || state == 3) {
				for (int k = 0; k < check.length; k++) {
					if (state == 1 || state == 2 || state == 4) {
						Idea i = Idea.findById(check[k]);
						i.state = state;
						i.save();
					} else if (state == 3) {
						user.communityContribution = user.communityContribution + 10;
						user.save();
						Idea i = Idea.findById(check[k]);
						i.state = state;
						i.save();
						Department department = Department.findById(did);
						boolean exist = false;
						for (int m = 0; m < department.executionCenter.size(); m++) {
							if (department.executionCenter.get(m).idea.id == i.id)
								exist = true;
						}
						if (exist == true)
							;
						else {
							PromotedIdea pi = new PromotedIdea(i).save();
							pi.users.add(i.author);
							pi.save();
							department.executionCenter.add(pi);
							department.save();
						}
					}
				}

				showTopic(tid, did);
			} else if (state == 5) {
				for (int k = 0; k < check.length; k++) {
					Idea ii = Idea.findById(check[k]);
					Topic t = Topic.findById(tid);
					List<User> toNotifyUsers = t.toBeNotified;
					for (int j = 0; j < toNotifyUsers.size(); j++) {
						User toNotify = toNotifyUsers.get(j);
						if (toNotify.notifyOnTopic) {
							String action = "Idea  " + ii.title
									+ " was deleted from topic " + t.title;
							Notification notif = new Notification(action, "System",
									toNotify, new Date());
							notif.save();
							Notification notificationToAuthor=new Notification(action,"System",ii.author,new Date());
							notificationToAuthor.save();
						}
					}
                    
					t.ideas.remove(ii);
					t.save();
					ii.delete();
				}

				showTopic(tid, did);
			} else if (state == 6) {

				Idea ii = Idea.findById(check[0]);
				for (int k = 1; k < check.length; k++) {
					Idea iii = Idea.findById(check[k]);
					ii.content = ii.content + iii.content;
					for (int m = 0; m < iii.comments.size(); m++) {
						Comment c = new Comment(iii.comments.get(m).content,
								iii.comments.get(m).user);
						c.pDate = iii.comments.get(m).pDate;
						c.save();
						ii.comments.add(c);

					}
					ii.save();
					Topic t = Topic.findById(tid);
					t.ideas.remove(iii);
					t.save();
					iii.delete();
				}

				ideaView(ii.id, tid, did);
			} else {
				List<Idea> ideas = new ArrayList<Idea>();
				Topic t = Topic.findById(tid);
				Department d = Department.findById(did);
				User u = User.findById(uid);
				for (int k = 0; k < check.length; k++) {
					Idea i = Idea.findById(check[k]);
					ideas.add(i);
				}
				RequestMirging request = new RequestMirging(u, ideas, tid, did);
				request.save();
				requestedMirg();

			}
		}
			}

	}







	

	public static void createLabel() {
		render();
	}

	/**
	 * @author emam
	 * @param titel
	 *            take the titel of the label
	 * @param userId
	 *            to be able to identify the user who will create the label
	 */
	/*
	 * the method task is to create label for specifc user
	 */

	public static void Label(String titel) {
		long userId = Long.parseLong(session.get("userId"));
		User user = User.findById(userId);
		Label label = new Label(titel);
		label.save();
		user.labels.add(label);
		user.save();
		System.out.println(user.labels.size());
		viewMyLabels();
	}

	/**
	 * @author emam
	 * @param labelId
	 *            To get the label that the user wants to delete
	 */
	/*
	 * the method task is to delete specific label for the user
	 */
	public static void deleteLabel(Long[] labels) {
		for (int k = 0; k < labels.length; k++) {
			Label label = Label.findById(labels[k]);
			long userId = Long.parseLong(session.get("userId"));
			User user = User.findById(userId);
			user.labels.remove(label);
			user.save();
			label.delete();
			viewMyLabels();
		}
	}

	/**
	 * @author emam
	 * @param Ideas
	 *            to have the idea id to delete
	 * @param lId
	 *            to have the label id
	 */
	/*
	 * the method task is to delete idea in the label
	 */
	public static void deleteIdeaInLabel(long[] ids) {

		for (int k = 0; k < ids.length; k++) {
			IdeasInLabel idea = IdeasInLabel.findById(ids[k]);
			Label label = Label.findById(idea.labelId);
			label.ideas.remove((idea));
			label.save();
			idea.delete();
			viewMyLabels();
		}

	}

	/**
	 * @author emam
	 * @param label
	 *            To identify the label we need to view
	 */
	/*
	 * the method task is to view all ideas in the label
	 */

	public static void viewIdeasInLabel(long labelId) {
		Label label = Label.findById(labelId);
		render(label);

	}

	/**
	 * @author emam
	 */
	/*
	 * the method task is to view all the labels the user created
	 */
	public static void viewMyLabels() {
		long userId = Long.parseLong(session.get("userId"));
		User user = User.findById(userId);
		List<Label> labels = user.labels;
		render(labels, user);
	}

	/**
	 * It renders viewNotification.html
	 * 
	 * @author Shady
	 */
	public static void viewNotification() {
		long userId = Long.parseLong(session.get("userId"));
		List<Notification> notifications = Notification
				.retrieveNotificationsOfAUser(userId);
		User user = User.findById(userId);
		render(user, notifications);
	}

	/**
	 * It takes the Notification Id and set the Notification.viewed to true;
	 * 
	 * @author Shady
	 * 
	 * @param notificationId
	 *            long Notification ID
	 */

	public static void setNotificationAsViewed(long notificationId) {
		Notification notification = Notification.findById(notificationId);
		notification.setViewed();
		viewNotification();
	}

	public static void notificationSettings() {
		long userId = Long.parseLong(session.get("userId"));
		User user = User.findById(userId);
		render(user);
	}

	public static void setNotificationSettings(boolean onOrganization,
			boolean onDepartment, boolean onTopic, boolean onIdea, boolean onTag) {
		long userId = Long.parseLong(session.get("userId"));
		User user = User.findById(userId);
		user.notifyOnOrganization = onOrganization;
		user.notifyOnDepartment = onDepartment;
		user.notifyOnTopic = onTopic;
		user.notifyOnIdea = onIdea;
		user.notifyOnTag = onTag;
		user.save();
		validation.addError("confirm", "Settings saved");
		validation.keep();
		notificationSettings();
	}

	public static void clearNotifications() {
		long userId = Long.parseLong(session.get("userId"));
		List<Notification> notifications = Notification
				.retrieveNotificationsOfAUser(userId);
		for (int i = 0; i < notifications.size(); i++) {
			Notification notif = Notification.findById(notifications.get(i).id);
			notif.delete();
		}
		viewNotification();
	}

	/**
	 * @author Daniel Riad
	 * @param depId
	 *            : This is the Id of the department I want to lock. This method
	 *            simply takes in as a parameter the ID of the department I want
	 *            to lock and it locks it by setting the isLocked variable to
	 *            true.
	 */

	public static void lockDepartment(long depId) {
		Department dep = Department.findById(depId);
		dep.isLocked = true;
		dep.save();
		List<User> toNotifyUsers = dep.toBeNotified;
		for (int j = 0; j < toNotifyUsers.size(); j++) {
			User toNotify = toNotifyUsers.get(j);
			if (toNotify.notifyOnDepartment) {
				String action = "Department   " + dep.name + " is now locked";
				Notification notif = new Notification(action, "System",
						toNotify, new Date());
				notif.save();
			}
		}
		viewDepartment(depId);
	}

	/**
	 * @author Daniel Riad
	 * @param depId
	 *            :This is the Id of the department that i want to unlock. This
	 *            method takes in the locked department's id, and simply unlocks
	 *            it by setting the isLocked variable to false.
	 */

	public static void unlockDepartment(long depId) {
		Department dep = Department.findById(depId);
		dep.isLocked = false;
		dep.save();
		List<User> toNotifyUsers = dep.toBeNotified;
		for (int j = 0; j < toNotifyUsers.size(); j++) {
			User toNotify = toNotifyUsers.get(j);
			if (toNotify.notifyOnDepartment) {
				String action = "Department   " + dep.name + " is now unlocked";
				Notification notif = new Notification(action, "System",
						toNotify, new Date());
				notif.save();
			}
		}
		viewDepartment(depId);
	}

	public static boolean roleIsIdeaDeveloper() {

		long userId = Long.parseLong(session.get("userId"));
		long orgId = Long.parseLong(session.get("orgId"));
		HasRoleInOrganization x = HasRoleInOrganization.find(
				"User_id = ? AND Organization_id = ?", userId, orgId).first();
		if (x == null) {
			return false;
		} else {
			Role r = x.role;
			String s = r.role;
			if (s.equals("Idea Developer")) {
				return true;

			} else {
				return false;
			}
		}

	}

	/**
	 * @author Khaled Ramzy
	 * @param ideaId
	 *            Idea id
	 * @param commentId
	 *            comment id
	 * @param topicId
	 *            topic id
	 * @param departmentId
	 *            department id
	 */
	/*
	 * the method render the comment thagt will be qouted
	 */

	public static void quotedComment(long iid, long cid, long tid, long did) {
		Idea idea = Idea.findById(iid);
		Comment c = Comment.findById(cid);
		render(idea, c, tid, did);
	}

	/**
	 * @author Mohamed Medhat This method render the view of the link
	 *         "Restrict organizer From Department" and
	 *         "Restrict organizer From Topic"
	 */

	public static void restrictOrganizer() {
		long organizationId = Long.parseLong(session.get("orgId"));
		Organization org = Organization.findById(organizationId);
		render(org);
	}

	/**
	 * @author Mohamed Medhat This method render the view of restricting
	 *         Organizer from specific Department after pressing on the link
	 *         "Restrict organizer From Department" in which the user and the
	 *         department where the user is an organizer in are displayed to be
	 *         restricted
	 */
	public static void restrictOrganizerFromDepartment() {
		long id = Long.parseLong(session.get("orgId"));
		Organization org = Organization.findById(id);
		List<Department> departments = org.department;
		List<OrganizerInOrganization> allOrganizersInAllDepartments = new ArrayList<OrganizerInOrganization>();
		for (int i = 0; i < departments.size(); i++) {
			List<OrganizerInOrganization> organizersInDepartment = OrganizerInOrganization
					.find("Department_id", departments.get(i)).fetch();
			for (int j = 0; j < organizersInDepartment.size(); j++) {
				allOrganizersInAllDepartments
						.add(organizersInDepartment.get(j));
			}
		}
		boolean isOrgLead = roleIsOrgLead();
		render(org, allOrganizersInAllDepartments, isOrgLead);
	}
	
	/**
	 * @author Mohamed Medhat
	 * This method render the view of restricting Organizer from specific Topic 
	 * after pressing on the link "Restrict organizer From Topic" in which the user 
	 * and the department where the user is an organizer in and the topics are 
	 * displayed to be restrict the organizer from a specific topic
	 */

	public static void restrictOrganizerFromTopic() {
		long id = Long.parseLong(session.get("orgId"));
		Organization org = Organization.findById(id);
		List<Department> departments = org.department;
		List<OrganizerInOrganization> allOrganizersInAllDepartments = new ArrayList<OrganizerInOrganization>();
		for (int i = 0; i < departments.size(); i++) {
			List<OrganizerInOrganization> organizersInDepartment = OrganizerInOrganization
					.find("Department_id", departments.get(i)).fetch();
			for (int j = 0; j < organizersInDepartment.size(); j++) {
				allOrganizersInAllDepartments
						.add(organizersInDepartment.get(j));
			}
		}
		boolean isOrgLead = roleIsOrgLead();
		render(org, allOrganizersInAllDepartments, isOrgLead);
	}

	/**
		 * @author  Mohamed Medhat
		 * @param topicId
		 * @param userId
		 * This method restrict the ability of the organizer to have access to a 
		 * specific Topic by blocking the organizer from this topic using the table IdeaDeveloperBlockedFromTopic and adding a 
		 * validation that displays a message if the user tried to restrict the 
		 * organizer from a topic which is already blocked from him. 
		 */
	
	public static void doRestrictOrganizerFromTopic(long topicId, long userId) {
		if (topicId < 1) {
			validation.addError("message",
					"Please select topic to restrict from");
			validation.keep();
			restrictOrganizerFromTopic();
		}
		if (IdeaDeveloperBlockedFromTopic.count("User_id = ? AND Topic_id = ?",
				userId, topicId) == 1) {
			validation.addError("message",
					"User is already restricted from this topic before");
			validation.keep();
			restrictOrganizerFromTopic();
		} else {
			User user = User.findById(userId);
			Topic topic = Topic.findById(topicId);
			IdeaDeveloperBlockedFromTopic toRestrict = new IdeaDeveloperBlockedFromTopic(
					user, topic, "Organization Lead block", new Date());
			toRestrict.save();
			validation.addError("message", "User restricted successfully");
			validation.keep();
			restrictOrganizerFromTopic();
		}
	}

	/**
	 * @author Mohamed Medhat
	 * @param organizerInOrganizationId
	 * @param departmentId
	 *            This method restrict the ability of the organizer to have
	 *            access to a specific department by deleting the role of this
	 *            organizer from the table HasRoleInOrganization.
	 * 
	 */
	public static void doRestrictOrganizerFromDepartment(
			long organizerInOrganizationId) {
		long organizationId = Long.parseLong(session.get("orgId"));
		OrganizerInOrganization tempRole = OrganizerInOrganization
				.findById(organizerInOrganizationId);
		tempRole.delete();
		long tempId = 2;
		if (HasRoleInOrganization.count(
				"Organization_id = ? AND User_id = ? AND Role_id = ?",
				organizationId, tempRole.user.id, tempId) == 1) {
			HasRoleInOrganization roleInOrganization = HasRoleInOrganization
					.find("Organization_id = ? AND User_id = ? AND Role_id = ?",
							organizationId, tempRole.user.id, tempId).first();
			roleInOrganization.delete();
			List<User> toNotifyUsers = tempRole.department.toBeNotified;
			for (int j = 0; j < toNotifyUsers.size(); j++) {
				User toNotify = toNotifyUsers.get(j);
				if (toNotify.notifyOnDepartment) {
					String action = "Organizer " + tempRole.user.nickName
							+ " is restricted from department  "
							+ tempRole.department.name;

					Notification notif = new Notification(action, "System",
							toNotify, new Date());
					notif.save();
				}
			}
		}
		restrictOrganizerFromDepartment();
	}

	/**
	 * @author Hussien
	 * @param topicId
	 *            To be able to identify the Topic that will be deleted
	 * @param departmentId
	 *            To be able to identify the Department that have the topic
	 * 
	 *            This method make the organizer capable of deleting the topics
	 *            that has no Idea
	 */
	public static void deleteTopic(long topicId, long departmentId) {
		Topic topic = Topic.findById(topicId);
		Department department = Department.findById(departmentId);
		department.topics.remove(topic);
		department.save();
		List<User> toNotifyUsers = department.toBeNotified;
		for (int j = 0; j < toNotifyUsers.size(); j++) {
			User toNotify = toNotifyUsers.get(j);
			if (toNotify.notifyOnDepartment) {
				String action = "Topic  " + topic.title
						+ " is deleted from department " + department.name;
				Notification notif = new Notification(action, "System",
						toNotify, new Date());
				notif.save();
			}
		}

		topic.delete();
		viewDepartment(departmentId);
	}

	/**
	 * @author Daniel Riad
	 * @param topicId
	 *            : This is the id of the topic that I want to lock. This method
	 *            takes in as a parameter the topicId of the topic i want to
	 *            lock, and it simply sets the isLocked variable to true.
	 * 
	 */
	public static void lockTopic(long topicId) {
		Topic topic = Topic.findById(topicId);
		topic.isLocked = true;
		topic.save();
		List<User> toNotifyUsers = topic.toBeNotified;
		for (int j = 0; j < toNotifyUsers.size(); j++) {
			User toNotify = toNotifyUsers.get(j);
			if (toNotify.notifyOnTopic) {
				String action = "Topic  " + topic.title + " is now locked ";
				Notification notif = new Notification(action, "System",
						toNotify, new Date());
				notif.save();
			}
		}
		viewTopicById(topicId);

	}

	/**
	 * @author Daniel Riad
	 * @param topicId
	 *            : this method simply takes in the id of the topic that I want
	 *            to unlock and sets the isLocked variable to false.
	 */
	public static void unlockTopic(long topicId) {
		Topic topic = Topic.findById(topicId);
		topic.isLocked = false;
		topic.save();
		List<User> toNotifyUsers = topic.toBeNotified;
		for (int j = 0; j < toNotifyUsers.size(); j++) {
			User toNotify = toNotifyUsers.get(j);
			if (toNotify.notifyOnTopic) {
				String action = "Topic  " + topic.title + " is now unlocked ";
				Notification notif = new Notification(action, "System",
						toNotify, new Date());
				notif.save();
			}
		}
		viewTopicById(topicId);
	}

	/**
	 * @author Daniel Riad
	 * @param id
	 *            : this is the Id of the user that is logged in This method
	 *            simply takes in the Id of the user that is logged in, loads
	 *            it, and renders it.
	 */
	public static void userPhoto(long id) {
		final User user = User.findById(id);
		notFoundIfNull(user);
		response.setContentTypeIfNotSet(user.profilePicture.type());
		renderBinary(user.profilePicture.get());
	}

	/**
	 * @author Nada mohamed
	 * @return List<User> in this method i get from the user class the count of
	 *         community contributions he made and i sorte it ascendingly to be
	 *         displayed in the home page
	 * 
	 */
	public static List<User> communityContributionsList() {
		return User.find("order by communityContribution asc").fetch();
	}

	/**
	 * @author Khaled Ramzy
	 * @param did
	 *            take the department ID
	 */
	/*
	 * the method view the the executionCenter view
	 */
	public static void executionCenter(long departmentId) {
		if (departmentId == 0) {
			List<Department> departments = Department.findAll();

			long id = Long.parseLong(session.get("orgId"));
			render(departments, id);
		} else {
			Department department = Department.findById(departmentId);
			List<Department> departments = new ArrayList();
			departments.add(department);
			long id = departmentId;
			render(departments, id);
		}
	}

	/**
	 * @author Khaled Ramzy
	 * @param did
	 *            take the department ID
	 * @param pid
	 *            promotedIdea id
	 */
	/*
	 * the method view the promotedIdea view
	 */
	public static void promotedIdea(long did, long pid) {
		PromotedIdea promoted = PromotedIdea.findById(pid);
		render(promoted, did);
	}

	/**
	 * @author Khaled Ramzy
	 * @param did
	 *            take the department ID
	 * @param pid
	 *            promotedIdea id
	 * @param tid
	 *            task id
	 */
	/*
	 * the method view the task
	 */
	public static void taskView(long did, long pid, long tid) {
		Task task = Task.findById(tid);
		render(task, did, pid);
	}

	/**
	 * @author Khaled Ramzy
	 * @param did
	 *            take the department ID
	 * @param pid
	 *            promotedIdea id
	 */
	/*
	 * the method render the page of creating the idea
	 */
	public static void createTask(long did, long pid) {

		render(did, pid);
	}

	/**
	 * @author Khaled Ramzy
	 * @param did
	 *            take the department ID
	 * @param pid
	 *            promotedIdea id
	 * @param title
	 *            the title of the task
	 * @param content
	 *            the content of the task
	 * @param state
	 *            represent the value returned by state DropDownList in the view
	 * @param priority
	 *            represent the value returned by priority DropDownList in the
	 *            view
	 */
	/*
	 * the method create tasks
	 */
	public static void taskCreated(long did, long pid, String title,
			String content, int priority, int state) {
		long ui = Long.parseLong(session.get("userId"));
		User user = User.findById(ui);
		PromotedIdea pi = PromotedIdea.findById(pid);
		Department d = Department.findById(did);
		Task task = new Task(user, title, content, priority, state);
		task.save();
		pi.tasks.add(task);
		pi.save();
		d.save();
		taskView(did, pid, task.id);

	}

	/**
	 * @author Khaled Ramzy
	 * @param did
	 *            take the department ID
	 * @param pid
	 *            promotedIdea id
	 * @parm tid task ID
	 * @param content
	 *            String of the text writen in the textArea
	 */
	/*
	 * the method taks the comment string and add it to the task comment list
	 */

	public static void addTaskComment(long did, long pid, long tid,
			String content) {
		long ui = Long.parseLong(session.get("userId"));
		Task task = Task.findById(tid);
		User user = User.findById(ui);
		Comment comment = new Comment(content, user).save();
		task.comments.add(comment);
		task.save();
		taskView(did, pid, tid);
	}

	/**
	 * @author Khaled Ramzy
	 * @param did
	 *            take the department ID
	 * @param pid
	 *            promotedIdea id
	 * @parm tid task ID
	 * @param state
	 *            represent the value returned by state DropDownList in the view
	 * @param priority
	 *            represent the value returned by priority DropDownList in the
	 *            view
	 * @param userId
	 *            to be able to identify the user who will create the label
	 */
	/*
	 * the method update the state of the task and its priority
	 */

	public static void taskUpdate(long did, long pid, long tid, int state,
			int priority) {
		Task task = Task.findById(tid);

		if (state != task.state)
			task.state = state;
		if (priority != task.priorety)
			task.priorety = priority;

		task.save();
		taskView(did, pid, tid);
	}

	/**
	 * @author Khaled Ramzy
	 * @param depId
	 *            take the department id
	 * @param proId
	 *            take the promotedIdea id
	 * @param userName
	 *            takes the userName entered by the user
	 */
	/*
	 * This method add user to the promotedIdea users list
	 */
	public static void addUserToPromotedIdea(long depId, long proId,
			String userName) {
		PromotedIdea pi = PromotedIdea.findById(proId);
		List<User> user = User.find("nickName=?", userName).fetch();
		if (user.size() == 0 || pi.users.contains(user.get(0)))
			;
		else
			pi.users.add(user.get(0));
		promotedIdea(depId, proId);
	}

	/**
	 * 
	 * @author Salma youssef
	 * @param the
	 *            topic id
	 */
	/*
	 * the method is used for Unblocking a user to be able to see a specific
	 * topic, after the organizer unblock the user he sends a notification to
	 * the user and to all the organizers in this organization and render the
	 * organization, the topic, and list of all ideas developers, and list of
	 * idea developers who are blocked to see this topic
	 */

	public static void blockTopic(long topicId) {
		long organizationId = Long.parseLong(session.get("orgId"));
		Organization organization = Organization.findById(organizationId);
		Topic topic = Topic.findById(topicId);
		List<HasRoleInOrganization> allIdeaDevelopers = HasRoleInOrganization
				.find("Organization_id = ? AND Role_Id = ?", organizationId,
						(long) 3).fetch();
		List<IdeaDeveloperBlockedFromTopic> blockedList = IdeaDeveloperBlockedFromTopic
				.find("Topic_id = ? ", topicId).fetch();
		render(organization, topic, allIdeaDevelopers, blockedList);
	}

	/**
	 * 
	 * @author Salma youssef
	 * @param topic
	 *            id
	 * @param user
	 *            id
	 * @param reason
	 *            of the blocking
	 */
	/*
	 * the method is used for blocking a user to be able not to see or to edit a
	 * specific topic, after the organizer block the user he sends a
	 * notification to the user and to all the organizers in this organization
	 */

	public static void blockUserFromTopic(
			long userId,
			long topicId,
			@Required(message = "Please Spicify the reason of Block") String reason) {
		if (validation.hasErrors()) {
			validation.keep();
			blockTopic(topicId);
		}
		if (userId < 1) {
			validation.addError("reason", "Please Select the user");
			validation.keep();
			blockTopic(topicId);
		} else {
			User user = User.findById(userId);
			Topic topic = Topic.findById(topicId);
			if (IdeaDeveloperBlockedFromTopic.count(
					"Topic_id = ? AND User_id = ?", topicId, userId) == 0) {
				Date inDate = new Date();
				IdeaDeveloperBlockedFromTopic newUserBlocked = new IdeaDeveloperBlockedFromTopic(
						user, topic, reason, inDate);
				long organizationId = Long.parseLong(session.get("orgId"));
				Organization organization = Organization
						.findById(organizationId);
				long organizerId = Long.parseLong(session.get("userId"));
				User organizer = User.findById(organizerId);
				String action = "You have been blocked by "
						+ organizer.nickName + " of the Organization "
						+ organization.name + " because: " + reason;
				Notification notify = new Notification(action,
						organizer.nickName, user, inDate);
				newUserBlocked.save();
				notify.save();
				List<HasRoleInOrganization> organizersList = HasRoleInOrganization
						.find("Organization_id = ? AND Role_id = ?",
								organization.id, (long) 2).fetch();
				for (int i = 0; i < organizersList.size(); i++) {
					HasRoleInOrganization organizerRole = organizersList.get(i);
					User theOrganizer = organizerRole.user;
					if (organizer.notifyOnDepartment
							&& organizer.notifyOnOrganization) {
						action = "User " + user.nickName
								+ " have been blocked by " + organizer.nickName
								+ " because: " + reason;
						Notification notifForOrganizer = new Notification(
								action, "System", organizer, inDate);
						notifForOrganizer.save();
					}

				}
				validation.addError("reason", "User Has Been Blocked");
				validation.keep();
				blockTopic(topicId);
			} else {
				validation.addError("reason",
						"User Has Been already Blocked before");
				validation.keep();
				blockTopic(topicId);
			}
		}
	}

	/**
	 * 
	 * @author Salma youssef
	 * @param topic
	 *            id
	 * @param user
	 *            id
	 * @param reason
	 *            of the unblocking
	 */
	/*
	 * the method is used for Unblocking a user to be able to see and edit a
	 * specific topic, after the organizer unblock the user he sends a
	 * notification to the user and to all the organizers in this organization
	 */

	public static void unblockUserFromTopic(
			long topicId,
			long userId,
			@Required(message = "Please Spicify the reason of Block") String reason) {
		if (userId < 1) {
			validation.addError("reason", "Please Select the user");
			validation.keep();
			blockTopic(topicId);
		}
		if (validation.hasErrors()) {
			validation.keep();
			blockTopic(topicId);
		} else {
			User user = User.findById(userId);
			Date inDate = new Date();
			IdeaDeveloperBlockedFromTopic unblockUser = IdeaDeveloperBlockedFromTopic
					.find("Topic_id = ? AND User_id = ?", topicId, userId)
					.first();
			unblockUser.delete();

			long organizationId = Long.parseLong(session.get("orgId"));
			Organization organization = Organization.findById(organizationId);
			long organizerId = Long.parseLong(session.get("userId"));
			User organizer = User.findById(organizerId);
			String action = "You have been unblocked by " + organizer.nickName
					+ " of Organization " + organization.name + " because: "
					+ reason;
			Notification notify = new Notification(action, organizer.nickName,
					user, inDate);
			notify.save();
			List<HasRoleInOrganization> organizerList = HasRoleInOrganization
					.find("Organization_id = ? AND Role_id = ?",
							organization.id, (long) 2).fetch();
			for (int i = 0; i < organizerList.size(); i++) {
				HasRoleInOrganization organizerRole = organizerList.get(i);
				User theOrganizer = organizerRole.user;
				if (organizer.notifyOnDepartment
						&& organizer.notifyOnOrganization) {
					action = "User " + user.nickName
							+ " have been unblocked by " + organizer.nickName
							+ " because: " + reason;
					Notification notifForOrganizer = new Notification(action,
							"System", organizer, inDate);
					notifForOrganizer.save();
				}

			}
			validation.addError("reason", "User Has Been Unblocked");
			validation.keep();
			blockTopic(topicId);
		}
		}
	
	/**
	 * @author Khalid Osama
	 * @param departmentId
	 * this method forms the request and filters the members of the organization which are already following the department 
	 */
		
		public static void requestForm(long departmentId){
        	long orgId=Long.parseLong(session.get("orgId"));
        	System.out.println("the organization ID is"+orgId);
        	Organization org=Organization.findById(orgId);
        	Department department=Department.findById(departmentId);
        	List<User>orgMembers=new ArrayList<User>();
        	for(int i=0;i<org.toBeNotified.size();i++)
        	{
        		if(department.toBeNotified.contains(org.toBeNotified.get(i)));
        		else
        			orgMembers.add(org.toBeNotified.get(i));	
        	}
        	long userId1=Long.parseLong(session.get("userId"));
        	User user=User.findById(userId1);
        	org.toBeNotified.add(user);
        	
        	render(orgMembers,departmentId,orgId);
        }
        
		/**
		 * @author Khalid Osama
		 * @param depId
		 * @param orgId
		 * @param userId
		 * @param content
		 * this method creates the actual request and places on the page of requests of the user
		 */
        public static void createRequest(long depId,long orgId,long[] userId,String content){
        	Department dep=Department.findById(depId);
        	String request=content+"the department: "+dep.name;
            long userID=Long.parseLong(session.get("userId"));
        	User user=User.findById(userID);
        	System.out.println("the size of the array of ids is "+userId.length);
        	
        	for(int i=0;i<userId.length;i++)
        	{
            	User reciver=User.findById(userId[i]);
                RequestFollower requestfollower=new RequestFollower(user,user,request,depId,orgId).save();
            	reciver.requests.add(requestfollower);
            	reciver.save();
            	System.out.println(reciver.requests.size());
        	}
        	
        	viewDepartment(depId);
        	
        }
        /**
         * @author Khalid Osama
         * this method show the request on the profile of the user
         */
        
        public static void followerRequestView(){
        	long userId=Long.parseLong(session.get("userId"));
        	User user=User.findById(userId);
        	List<RequestFollower> list=user.requests;
        	System.out.println("the length of the RF list "+ list.size());
        	render(list);
        }
        /**
         * @author Khalid Osama
         * @param frId the follower request id
         * @param proceed to know which thing did he choose accept or ignore
         * this method manages the reuqests from the reciever side
         */
        
        
        public static void manageFollowerRequest(long frId, int proceed){
  		RequestFollower req=RequestFollower.findById(frId);
  		  if(proceed==1)
  		  {
  			  Department department=Department.findById(req.depId);
  			  department.toBeNotified.add(req.reciver);
  			  department.save();
  			  User user=req.reciver;
    		 user.requests.remove(req);
      		 user.save();
  			 followerRequestView();
  		  }
  		  else if (proceed==2)
  		  {
  			  User user=req.reciver;
  			user.requests.remove(req);
  			user.save();
  			followerRequestView();
  		  }
  	  }
        

	

	/**
	 * 
	 * @author Salma youssef
	 * @param topic
	 *            id
	 * @param user
	 *            id
	 * @param reason
	 *            of the unblocking
	 */
	/*
	 * the method is used for checking if the specified user is already blocked
	 * from veiwing and editing a specific topic or not, if the method return
	 * true then the user is blocked if not then the user isnt blocked from
	 * viewing this topic
	 */
	public static boolean isBlockedFromTopic(long topicId, long userId) {
		if (IdeaDeveloperBlockedFromTopic.count("Topic_id = ? AND User_id = ?",
				topicId, userId) == 1) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * @author Khalid OSama
	 * @param depId
	 *            to get the department this method merely adds the user to the
	 *            list of followers of the Department by getting the user from
	 *            the session.
	 */
	public static void followDep(Long depId) {
		long id = Long.parseLong(session.get("userId"));
		User user = User.findById(id);
		Department dep = Department.findById(depId);
		if (validation.hasErrors()) {
			validation.keep();
		}
		dep.addFollowers(user);
		dep.save();
		viewDepartment(depId);
	}

	/**
	 * @author Khalid Osama
	 * @param orgId
	 *            to get the organization this method merely adds the user to
	 *            the list of followers of the Organization and get the user
	 *            that is added from the session.
	 */

	// Organization org;
	// long b=org.id;

	public static void followOrg(long orgId) {
		long id = Long.parseLong(session.get("userId"));
		User user = User.findById(id);
		Organization org = Organization.findById(orgId);
		if (validation.hasErrors()) {
			validation.keep();
		}
		org.addFollowers(user);
		org.save();
		showOrg(orgId);
		

	}

	/**
	 * @author Khalid Osama
	 * @param topicId
	 *            to get the topic this method merely adds the user to the list
	 *            of followers of the topic and get the user from the session to
	 *            add him to the list.
	 */

	public static void followTopic(long tid) {
		long id = Long.parseLong(session.get("userId"));
		User user = User.findById(id);
		Topic topic = Topic.findById(tid);
		if (validation.hasErrors()) {
			validation.keep();
		}
		topic.addFollowers(user);
		topic.save();
		viewTopicById(tid);
	}

/**
	 * @author Kareem Lala
	 * This method sends a message to the organization lead of a private
	 * organization which the Idead Developer request to join.
	 */
	public static void requestToJoinPrivateOrg() {
		long userID = Long.parseLong(session.get("userId"));
		User user= User.findById(userID);
		long organizationID = Long.parseLong(session.get("orgId"));
		String x= "Organization Lead";
		HasRoleInOrganization isOrgLead = HasRoleInOrganization.find("Organization_id = ? AND Role_role = ?",organizationID,x).first();
		User orgLead = User.findById(isOrgLead.user.id);
		Request req = new Request(orgLead,"User :"+user.nickName+" Requests To join your Private Organization",""+organizationID);
		validation.addError("set", "The Request has been sent successfully.");
		validation.keep();
		requestToJoinPrivateOrg();
		}

}
